<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:epub="http://www.idpf.org/2007/ops" lang="en" xml:lang="en">
<head>
<meta name="generator" content="HTML Tidy for HTML5 for Windows version 5.7.28"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="copyright" content="(C) Copyright 2018"/>
<meta name="DC.rights.owner" content="(C) Copyright 2018"/>
<title>Base Platform ABI for the Arm® Architecture - ABI 2018Q4
documentation</title>

<meta name="keywords" content="Fast Models"/></head>
<body>
<h2>Base Platform ABI for the Arm Architecture</h2>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div id="base-platform-abi-for-the-arm-architecture">
<p>Document number: IHI 0037D, current through ABI release
2018Q4</p>
<p>Date of Issue: 21<sup>st</sup> December 2018</p>

<div>
<div>
<div>
<div id="preamble">
<h2>Preamble</h2>
<div>
<div>
<div>
<div id="abstract">
<h3>Abstract</h3>
<p>This document describes the Base Platform Application Binary
Interface for the Arm architecture. This is the base standard for
the interface between executable files (including dynamic shared
objects, DLLs, etc) and the systems that execute them.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="keywords">
<h3>Keywords</h3>
<p>Executable file format and contents, dynamic shared object
(DSO), dynamic link library (DLL), executable file loading, dynamic
linking.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="how-to-find-the-latest-release-of-this-specification-or-report-a-defect-in-it">
<h3>How to find the latest release of this specification or report
a defect in it</h3>
<p>Please check the Arm Developer site (<a href="https://developer.arm.com/products/software-development-tools/specifications">https://developer.arm.com/products/software-development-tools/specifications</a>)
for a later release if your copy is more than one year old.</p>
<p>Please report defects in this specification to <em>arm</em> dot
<em>eabi</em> at <em>arm</em> dot <em>com</em>.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="licence">
<h3>Licence</h3>
<p>THE TERMS OF YOUR ROYALTY FREE LIMITED LICENCE TO USE THIS ABI
SPECIFICATION ARE GIVEN IN <a href="index.html#your-licence-to-use-this-specification">Your licence to use this
specification</a> (Arm contract reference LEC-ELA-00081 V2.0).
PLEASE READ THEM CAREFULLY.</p>
<p>BY DOWNLOADING OR OTHERWISE USING THIS SPECIFICATION, YOU AGREE
TO BE BOUND BY ALL OF ITS TERMS. IF YOU DO NOT AGREE TO THIS, DO
NOT DOWNLOAD OR USE THIS SPECIFICATION. THIS ABI SPECIFICATION IS
PROVIDED "AS IS" WITH NO WARRANTIES (SEE <a href="index.html#your-licence-to-use-this-specification">Your licence to use this
specification</a> FOR DETAILS).</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="non-confidential-proprietary-notice">
<h3>Non-Confidential Proprietary Notice</h3>
<p>This document is protected by copyright and other related rights
and the practice or implementation of the information contained in
this document may be protected by one or more patents or pending
patent applications. No part of this document may be reproduced in
any form by any means without the express prior written permission
of Arm. No license, express or implied, by estoppel or otherwise to
any intellectual property rights is granted by this document unless
specifically stated.</p>
<p>Your access to the information in this document is conditional
upon your acceptance that you will not use or permit others to use
the information for the purposes of determining whether
implementations infringe any third party patents.</p>
<p>THIS DOCUMENT IS PROVIDED "AS IS". ARM PROVIDES NO
REPRESENTATIONS AND NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY,
INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, SATISFACTORY QUALITY, NON-INFRINGEMENT OR FITNESS
FOR A PARTICULAR PURPOSE WITH RESPECT TO THE DOCUMENT. For the
avoidance of doubt, Arm makes no representation with respect to,
and has undertaken no analysis to identify or understand the scope
and content of, patents, copyrights, trade secrets, or other
rights.</p>
<p>This document may include technical inaccuracies or
typographical errors.</p>
<p>TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL ARM BE
LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION ANY DIRECT,
INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES,
HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING
OUT OF ANY USE OF THIS DOCUMENT, EVEN IF ARM HAS BEEN ADVISED OF
THE POSSIBILITY OF SUCH DAMAGES.</p>
<p>This document consists solely of commercial items. You shall be
responsible for ensuring that any use, duplication or disclosure of
this document complies fully with any relevant export laws and
regulations to assure that this document or any portion thereof is
not exported, directly or indirectly, in violation of such export
laws. Use of the word "partner" in reference to Arm's customers is
not intended to create or refer to any partnership relationship
with any other company. Arm may make changes to this document at
any time and without notice.</p>
<p>If any of the provisions contained in these terms conflict with
any of the provisions of any click through or signed written
agreement covering this document with Arm, then the click through
or signed written agreement prevails over and supersedes the
conflicting provisions of these terms. This document may be
translated into other languages for convenience, and you agree that
if there is any conflict between the English version of this
document and any translation, the terms of the English version of
the Agreement shall prevail.</p>
<p>The Arm corporate logo and words marked with ® or ™ are
registered trademarks or trademarks of Arm Limited (or its
subsidiaries) in the US and/or elsewhere. All rights reserved.
Other brands and names mentioned in this document may be the
trademarks of their respective owners. Please follow Arm's
trademark usage guidelines at <a href="http://www.arm.com/company/policies/trademarks">http://www.arm.com/company/policies/trademarks</a>.</p>
<p>Copyright © [2018] Arm Limited or its affiliates. All rights
reserved.</p>
<p>Arm Limited. Company 02557590 registered in England. 110
Fulbourn Road, Cambridge, England CB1 9NJ. LES-PRE-20349</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="contents">
<h3>Contents</h3>
<div>
<div>
<div>
<div id="id1">
<p>Contents</p>
<ul>
<li><a href="index.html#base-platform-abi-for-the-arm-architecture" id="id14">Base Platform ABI for the Arm® Architecture</a>
<ul>
<li><a href="index.html#preamble" id="id15">Preamble</a>
<ul>
<li><a href="index.html#abstract" id="id16">Abstract</a></li>
<li><a href="index.html#keywords" id="id17">Keywords</a></li>
<li><a href="index.html#how-to-find-the-latest-release-of-this-specification-or-report-a-defect-in-it" id="id18">How to find the latest release of this
specification or report a defect in it</a></li>
<li><a href="index.html#licence" id="id19">Licence</a></li>
<li><a href="index.html#non-confidential-proprietary-notice" id="id20">Non-Confidential Proprietary Notice</a></li>
<li><a href="index.html#contents" id="id21">Contents</a></li>
</ul>
</li>
<li><a href="index.html#about-this-document" id="id22">About This
Document</a>
<ul>
<li><a href="index.html#change-control" id="id23">Change
control</a></li>
<li><a href="index.html#references" id="id24">References</a></li>
<li><a href="index.html#terms-and-abbreviations" id="id25">Terms
and abbreviations</a></li>
<li><a href="index.html#your-licence-to-use-this-specification" id="id26">Your licence to use this specification</a></li>
<li><a href="index.html#acknowledgements" id="id27">Acknowledgements</a></li>
</ul>
</li>
<li><a href="index.html#introduction-and-rationale" id="id28">Introduction and Rationale</a>
<ul>
<li><a href="index.html#the-role-of-this-standard-in-the-abi-for-the-arm-architecture" id="id29">The role of this standard in the ABI for the
Arm Architecture</a></li>
<li><a href="index.html#base-platform-categories" id="id30">Base
platform categories</a></li>
<li><a href="index.html#the-base-platform-abi-tool-flow" id="id31">The base platform ABI tool flow</a></li>
<li><a href="index.html#making-sense-of-abi-supported-addressing-modes" id="id32">Making sense of ABI-supported addressing
modes</a></li>
<li><a href="index.html#relating-executables-and-shared-objects-to-executable-files" id="id33">Relating executables and shared objects to
executable files</a></li>
<li><a href="index.html#base-platform-static-linking-and-post-linking" id="id34">Base platform static linking and post
linking</a></li>
</ul>
</li>
<li><a href="index.html#the-base-platform-abi-specification" id="id35">The Base Platform ABI Specification</a>
<ul>
<li><a href="index.html#scope-and-terminology" id="id36">Scope
and terminology</a></li>
<li><a href="index.html#executable-file-format" id="id37">Executable file format</a></li>
<li><a href="index.html#symbol-binding-and-versioning" id="id38">Symbol binding and versioning</a></li>
<li><a href="index.html#procedure-linkage-and-other-intra-call-veneers" id="id39">Procedure linkage and other intra-call
veneers</a></li>
<li><a href="index.html#data-linkage-and-plt-got-generation-by-complying-linkers" id="id40">Data linkage and [PLT]GOT generation by
complying linkers</a></li>
<li><a href="index.html#encoding-symbol-pre-emption-in-bpabi-executable-files" id="id41">Encoding symbol pre-emption in BPABI executable
files</a></li>
<li><a href="index.html#obligations-on-static-linkers-in-support-of-post-linking" id="id42">Obligations on static linkers in support of post
linking</a></li>
</ul>
</li>
<li><a href="index.html#summary-of-platform-specific-considerations" id="id43">Summary of Platform-Specific Considerations</a>
<ul>
<li><a href="index.html#differences-between-svr4-and-bpabi-executable-files" id="id44">Differences between SVr4 and BPABI executable
files</a></li>
<li><a href="index.html#differences-between-linking-for-svr4-and-the-bpabi" id="id45">Differences between linking for SVr4 and the
BPABI</a></li>
</ul>
</li>
<li><a href="index.html#some-post-linking-sketches" id="id46">Some Post Linking Sketches</a>
<ul>
<li><a href="index.html#post-linking-for-linux" id="id47">Post
linking for Linux</a></li>
<li><a href="index.html#post-linking-for-dll-like-linkage" id="id48">Post linking for DLL-like linkage</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="about-this-document">
<h2>About This Document</h2>
<div>
<div>
<div>
<div id="change-control">
<h3>Change control</h3>
<div>
<div>
<div>
<div id="current-status-and-anticipated-changes">
<h4>Current status and anticipated changes</h4>
<p>The following support level definitions are used by the Arm ABI
specifications:</p>
<ul>
<li>ReleaseArm considers this specification to have enough
implementations, which have received sufficient testing, to verify
that it is correct. The details of these criteria are dependent on
the scale and complexity of the change over previous versions:
small, simple changes might only require one implementation, but
more complex changes require multiple independent implementations,
which have been rigorously tested for cross-compatibility. Arm
anticipates that future changes to this specification will be
limited to typographical corrections, clarifications and compatible
extensions.</li>
<li>BetaArm considers this specification to be complete, but
existing implementations do not meet the requirements for
confidence in its release quality. Arm may need to make
incompatible changes if issues emerge from its implementation.</li>
<li>AlphaThe content of this specification is a draft, and Arm
considers the likelihood of future incompatible changes to be
significant.</li>
</ul>
<p>All content in this document is at the "Release" quality
level.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="change-history">
<h4>Change history</h4>
<table>
<colgroup>
<col width="6%"/>
<col width="30%"/>
<col width="3%"/>
<col width="61%"/></colgroup>
<thead valign="bottom">
<tr>
<th>Issue</th>
<th>Date</th>
<th>By</th>
<th>Change</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>2.0</td>
<td>24<sup>th</sup> March 2005</td>
<td>LS</td>
<td>First public release.</td>
</tr>
<tr>
<td>A</td>
<td>25<sup>th</sup> October 2007</td>
<td>LS</td>
<td>Document renumbered (formerly GENC-005700 v2.0).</td>
</tr>
<tr>
<td>B</td>
<td>10<sup>th</sup> October 2008</td>
<td>LS</td>
<td>Changed depth-first to the intended breadth-first in <a href="index.html">Obligations on static linkers generating
pre-emption maps</a>; made a minor correction to the dllimport
example at the end of <a href="index.html">The DLL
model and indirect addressing of imported entities</a>.</td>
</tr>
<tr>
<td>C</td>
<td>30<sup>th</sup> November 2012</td>
<td>AC</td>
<td><a href="index.html">Adding export and import
tables (if required)</a>: Clarify STB_WEAK definitions are treated
as equivalent to STB_GLOBAL when generating a Windows-style export
table. <a href="index.html">Post linking for DLL-like
linkage</a>: Give more details on export rules.</td>
</tr>
<tr>
<td>2018Q4</td>
<td>21<sup>st</sup> December 2018</td>
<td>OS</td>
<td>Minor typographical fixes, updated links.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="references">
<h3>References</h3>
<p>This document refers to, or is referred to by, the following
documents.</p>
<table>
<colgroup>
<col width="20%"/>
<col width="66%"/>
<col width="14%"/></colgroup>
<thead valign="bottom">
<tr>
<th>Ref</th>
<th>URL or other reference</th>
<th>Title</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td><a href="https://developer.arm.com/docs/ihi0044/latest">AAELF</a></td>
<td> </td>
<td>ELF for the Arm Architecture</td>
</tr>
<tr>
<td><a href="https://developer.arm.com/docs/ihi0042/latest">AAPCS</a></td>
<td> </td>
<td>Procedure Call Standard for the Arm Architecture</td>
</tr>
<tr>
<td><a href="https://developer.arm.com/docs/ihi0036/latest">BSABI</a></td>
<td> </td>
<td>ABI for the Arm Architecture (base standard)</td>
</tr>
<tr>
<td><a href="https://developer.arm.com/docs/ihi0041/latest">CPPABI</a></td>
<td> </td>
<td>C++ ABI for the Arm Architecture</td>
</tr>
<tr>
<td><a href="https://developer.arm.com/docs/ihi0043/latest">RTABI</a></td>
<td> </td>
<td>Run-time ABI for the Arm Architecture</td>
</tr>
<tr>
<td>BPABI</td>
<td>This document</td>
<td>Base Platform ABI for the Arm Architecture</td>
</tr>
<tr>
<td><a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a></td>
<td>
<p><a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">http://www.sco.com/developers/gabi/2001-04-24/contents.html</a></p>
<p><a href="http://refspecs.linuxfoundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/elf-generic.html">
http://refspecs.linuxfoundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/elf-generic.html</a></p>
</td>
<td>System V Application Binary Interface - DRAFT - 24 April
2001</td>
</tr>
<tr>
<td><a href="http://itanium-cxx-abi.github.io/cxx-abi/abi.html">GCPPABI</a></td>
<td><a href="http://itanium-cxx-abi.github.io/cxx-abi/abi.html">http://itanium-cxx-abi.github.io/cxx-abi/abi.html</a></td>
<td>Generic C++ ABI</td>
</tr>
<tr>
<td><a href="http://refspecs.linuxfoundation.org/LSB_2.0.1/LSB-Core/LSB-Core/noteabitag.html">
ABInote</a></td>
<td><a href="http://refspecs.linuxfoundation.org/LSB_2.0.1/LSB-Core/LSB-Core/noteabitag.html">
http://refspecs.linuxfoundation.org/LSB_2.0.1/LSB-Core/LSB-Core/noteabitag.html</a></td>
<td>Linux Standard Base Specification 2.0.1, Chapter 9. ABI note
tag</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="terms-and-abbreviations">
<h3>Terms and abbreviations</h3>
<p>The ABI for the Arm Architecture uses the following terms and
abbreviations.</p>
<ul>
<li>AAPCSProcedure Call Standard for the Arm Architecture</li>
<li>ABI
<p>Application Binary Interface:</p>
<ol>
<li>The specifications to which an executable must conform in order
to execute in a specific execution environment. For example, the
Linux ABI for the Arm Architecture.</li>
<li>particular aspect of the specifications to which independently
produced relocatable files must conform in order to be statically
linkable and executable. For example, the C++ ABI for the Arm
Architecture, the Run-time ABI for the Arm Architecture, the C
Library ABI for the Arm Architecture.</li>
</ol>
</li>
<li>AEABI(Embedded) ABI for the Arm architecture (this ABI...)</li>
<li>Arm-based... based on the Arm architecture ...</li>
<li>core registersThe general purpose registers visible in the Arm
architecture's programmer's model, typically r0-r12, SP, LR, PC,
and CPSR.</li>
<li>EABIAn ABI suited to the needs of embedded, and deeply embedded
(sometimes called free standing), applications.</li>
<li>Q-o-IQuality of Implementation - a quality, behavior,
functionality, or mechanism not required by this standard, but
which might be provided by systems conforming to it. Q-o-I is often
used to describe the tool-chain-specific means by which a standard
requirement is met.</li>
<li>VFPThe Arm architecture's Floating Point architecture and
instruction set. In this ABI, this abbreviation includes all
floating point variants regardless of whether or not vector (V)
mode is supported.</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="your-licence-to-use-this-specification">
<h3>Your licence to use this specification</h3>
<p>IMPORTANT: THIS IS A LEGAL AGREEMENT ("LICENCE") BETWEEN YOU (AN
INDIVIDUAL OR SINGLE ENTITY WHO IS RECEIVING THIS DOCUMENT DIRECTLY
FROM ARM LIMITED) ("LICENSEE") AND ARM LIMITED ("ARM") FOR THE
SPECIFICATION DEFINED IMMEDIATELY BELOW. BY DOWNLOADING OR
OTHERWISE USING IT, YOU AGREE TO BE BOUND BY ALL OF THE TERMS OF
THIS LICENCE. IF YOU DO NOT AGREE TO THIS, DO NOT DOWNLOAD OR USE
THIS SPECIFICATION.</p>
<p>"Specification" means, and is limited to, the version of the
specification for the Applications Binary Interface for the Arm
Architecture comprised in this document. Notwithstanding the
foregoing, "Specification" shall not include (i) the implementation
of other published specifications referenced in this Specification;
(ii) any enabling technologies that may be necessary to make or use
any product or portion thereof that complies with this
Specification, but are not themselves expressly set forth in this
Specification (e.g. compiler front ends, code generators, back
ends, libraries or other compiler, assembler or linker
technologies; validation or debug software or hardware;
applications, operating system or driver software; RISC
architecture; processor microarchitecture); (iii) maskworks and
physical layouts of integrated circuit designs; or (iv) RTL or
other high level representations of integrated circuit designs.</p>
<p>Use, copying or disclosure by the US Government is subject to
the restrictions set out in subparagraph (c)(1)(ii) of the Rights
in Technical Data and Computer Software clause at DFARS
252.227-7013 or subparagraphs (c)(1) and (2) of the Commercial
Computer Software - Restricted Rights at 48 C.F.R. 52.227-19, as
applicable.</p>
<p>This Specification is owned by Arm or its licensors and is
protected by copyright laws and international copyright treaties as
well as other intellectual property laws and treaties. The
Specification is licensed not sold.</p>
<ol>
<li>Subject to the provisions of Clauses 2 and 3, Arm hereby grants
to LICENSEE, under any intellectual property that is (i) owned or
freely licensable by Arm without payment to unaffiliated third
parties and (ii) either embodied in the Specification or Necessary
to copy or implement an applications binary interface compliant
with this Specification, a perpetual, non-exclusive,
non-transferable, fully paid, worldwide limited licence (without
the right to sublicense) to use and copy this Specification solely
for the purpose of developing, having developed, manufacturing,
having manufactured, offering to sell, selling, supplying or
otherwise distributing products which comply with the
Specification.</li>
<li>THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO WARRANTIES
EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO ANY
WARRANTY OF SATISFACTORY QUALITY, MERCHANTABILITY, NONINFRINGEMENT
OR FITNESS FOR A PARTICULAR PURPOSE. THE SPECIFICATION MAY INCLUDE
ERRORS. Arm RESERVES THE RIGHT TO INCORPORATE MODIFICATIONS TO THE
SPECIFICATION IN LATER REVISIONS OF IT, AND TO MAKE IMPROVEMENTS OR
CHANGES IN THE SPECIFICATION OR THE PRODUCTS OR TECHNOLOGIES
DESCRIBED THEREIN AT ANY TIME.</li>
<li>This Licence shall immediately terminate and shall be
unavailable to LICENSEE if LICENSEE or any party affiliated to
LICENSEE asserts any patents against Arm, Arm affiliates, third
parties who have a valid licence from Arm for the Specification, or
any customers or distributors of any of them based upon a claim
that a LICENSEE (or LICENSEE affiliate) patent is Necessary to
implement the Specification. In this Licence; (i) "affiliate" means
any entity controlling, controlled by or under common control with
a party (in fact or in law, via voting securities, management
control or otherwise) and "affiliated" shall be construed
accordingly; (ii) "assert" means to allege infringement in legal or
administrative proceedings, or proceedings before any other
competent trade, arbitral or international authority; (iii)
"Necessary" means with respect to any claims of any patent, those
claims which, without the appropriate permission of the patent
owner, will be infringed when implementing the Specification
because no alternative, commercially reasonable, non-infringing way
of implementing the Specification is known; and (iv) English law
and the jurisdiction of the English courts shall apply to all
aspects of this Licence, its interpretation and enforcement. The
total liability of Arm and any of its suppliers and licensors under
or in relation to this Licence shall be limited to the greater of
the amount actually paid by LICENSEE for the Specification or
US$10.00. The limitations, exclusions and disclaimers in this
Licence shall apply to the maximum extent allowed by applicable
law.</li>
</ol>
<p>Arm Contract reference LEC-ELA-00081 V2.0 AB/LS (9 March
2005)</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="acknowledgements">
<h3>Acknowledgements</h3>
<p>This specification has been developed with the active support of
the following organizations. In alphabetical order: Arm,
CodeSourcery, Intel, Metrowerks, Montavista, Nexus Electronics,
PalmSource, Symbian, Texas Instruments, and Wind River.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="introduction-and-rationale">
<h2>Introduction and Rationale</h2>
<div>
<div>
<div>
<div id="the-role-of-this-standard-in-the-abi-for-the-arm-architecture">
<h3>The role of this standard in the ABI for the Arm
Architecture</h3>
<p>This Base Platform ABI standardizes the interface between
executable files (including dynamic shared objects, dynamic link
libraries, and the like) and their execution environments (or
platforms). The Base Platform ABI completes version 2.0 of the ABI
for the Arm Architecture (base standard) by setting standards for
tools producing executable files usable in a wide range of
execution environments.</p>
<p>The ABI for the Arm Architecture [<a href="https://developer.arm.com/docs/ihi0036/latest">BSABI</a>] defines
four broad families of execution environment categorized by how
they manage the address space and how they handle dynamically
loaded binaries. This is summarized pictorially in the central area
of the figure below.</p>
<div class="documents-docsimg-container" id="id2"><img alt="bpabi32-execution-environment.png" src="bpabi32-execution-environment.png"/>
<p>Figure 1, Execution environment traits
determining the structure of the Base Platform ABI</p>
</div>
<p>The three platform categories that support dynamically loaded
shared libraries use two fundamentally different shared library
models. Two categories share some aspects of the Windows dynamic
link library (DLL) model while one uses the Linux-like dynamic
shared object (DSO) model. This is summarized in the upper area of
<a href="index.html">Figure 1, Execution environment traits
determining the structure of the Base Platform ABI</a>.</p>
<div>
<div>
<div>
<div id="relationship-to-v1-0-of-the-abi-for-the-arm-architecture">
<h4>Relationship to v1.0 of the ABI for the Arm Architecture</h4>
<p>Version 1.0 of the ABI for the Arm Architecture (base standard)
governs the interface between producers of relocatable files and
static linking. It guarantees little about the form or utility of
any executable file produced. Some aspects of target execution
environments show through version 1.0 in the procedure call
standard [<a href="https://developer.arm.com/docs/ihi0042/latest">AAPCS</a>] and the
run-time ABI [<a href="https://developer.arm.com/docs/ihi0043/latest">RTABI</a>] because
they affect code generation and, hence, the interface to
relocatable code. However, version 1.0 does not regulate the
interface to those execution environments.</p>
<p>Underpinning the variations between platform families are three
fundamentally different ways to address static data, depicted in
the lower region of <a href="index.html">Figure 1, Execution
environment traits determining the structure of the Base Platform
ABI</a> as procedure call standard or build option variants. In
fact there is a further dimension to this variation not depicted
there that doubles the number of ways to address imported static
data (discussed in <a href="index.html">Making sense of
ABI-supported addressing modes</a>).</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="base-platform-categories">
<h3>Base platform categories</h3>
<p>We categorize execution environments according to how they
organize the address space and whether they can dynamically load
shared objects. We then define a parameterized standard that works
across the categories.</p>
<p>In order of increasing conceptual complexity the four platform
categories are:</p>
<ul>
<li>
<p>Single address space, no dynamic shared objects
(often known as "bare metal" or the "bare platform").</p>
<p>Typically, a program is committed to read-only memory (or FLASH
memory). Loading and dynamic linking are performed off line before
creating a ROM image. If there is an operating system (often termed
an RTOS, micro-kernel or nano-kernel) it is statically linked into
the ROM image. An RTOS may, nonetheless, be able to load executable
files.</p>
</li>
<li>
<p>Single address space with DLL-like shared objects
(example: Palm OS).</p>
<p>The OS and some applications are committed to read-only memory,
but other modules can be loaded dynamically into RAM. At the user
level, loadable modules provide functionality similar to that of
Windows DLLs and executable files. The system and all its
applications exist in a single virtual address space.</p>
</li>
<li>
<p>Multiple address spaces with Windows-like
organization and DLL-like shared objects (example: Symbian OS).</p>
<p>DLL can be shared among several processes, each of which has its
own virtual address space. A segment of a DLL is mapped at the same
virtual address in each process that maps it. DLLs behave similarly
(but not identically) to Windows DLLs.</p>
</li>
<li>
<p>Multiple address spaces with SVr4-like
organization and SVr4-like DSOs (example: Arm Linux).</p>
<p>A DSO can be shared among several processes, each of which has
its own virtual address space. A segment of a DSO can be mapped at
a different virtual address in each process that maps it.</p>
</li>
</ul>
<p>(<strong>Aside</strong>: DSOs, DLLs, and executable files
structure systems at the highest level. Shared objects are useful
for structuring large systems for bare platforms if dynamic linking
and loading operations can be performed off line - in effect in a
second phase of static linking. Some bare platforms may also be
able to load executable files dynamically. <strong>End
aside</strong>).</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="the-base-platform-abi-tool-flow">
<h3>The base platform ABI tool flow</h3>
<p>This base platform ABI sets a standard for executable and shared
object files - in effect, a standard for the tool chains that
produce them. This ABI is based on the tool flow depicted
below.</p>
<p>A simple post-linker (see <a href="index.html">Simple
post linking</a> for our definition of simple) converts a
BPABI-conforming executable or shared object file into a
platform-specific format. The post linker is simple enough to be
supplied by a platform vendor.</p>
<p>conversion done this way can easily be built into a static
linker, at low cost. We expect that tool vendors serious about a
specific platform will do this.</p>
<p>Either way, the cost supporting a specific platform ABI derived
from this base platform ABI (under the simple post-linking
constraint) will be moderate.</p>
<div class="documents-docsimg-container" id="id3"><img alt="bpabi32-tool-flow.png" src="bpabi32-tool-flow.png"/>
<p>Figure 2, Base platform ABI tool flow and its
relationship to concrete platforms</p>
</div>
<p>Platform-specific elements are shown grayed. Others are generic
to all ABIs derived from this base platform ABI.</p>
<div>
<div>
<div>
<div id="simple-post-linking">
<h4>Simple post linking</h4>
<p>A BPABI post linker is a simple tool compared to a static
linker. Some bounds on its complexity are:</p>
<ul>
<li>
<p>Post linking must be at least as complex as
navigating a generic (ELF) executable file (or similar).</p>
<p>(This mirrors the structural complexity of utilities such as the
ADS/RVCT fromelf, the SUN/Solaris elfdump, the Linux objdump, and
the Windows dumpbin).</p>
</li>
<li>
<p>In general, post linking should not be more
complex than the most general form of dynamic linking (platform
specific aspects can increase the complexity arbitrarily, but
ABI-specific aspects do not).</p>
<p>(Among the concrete platforms under consideration, Linux has the
most complex behavior when an executable or shared object file is
loaded and linked dynamically. For platforms that do less
dynamically, the post linker must perform some of these dynamic
linking tasks off line. There is no more to do to prepare an
executable file for execution than SVr4 does dynamically).</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="making-sense-of-abi-supported-addressing-modes">
<h3>Making sense of ABI-supported addressing modes</h3>
<div>
<div>
<div>
<div id="basic-concepts-and-terminology">
<h4>Basic concepts and terminology</h4>
<div>
<div>
<div>
<div id="own-data">
<h5>Own data</h5>
<p>Programming languages such as C and C++ typically recognize
three fundamentally different classes of data.</p>
<ul>
<li>Local, automatic, or stack data (terminology varies) are
usually allocated to registers or the run-time stack. If any datum
is in memory and needs to be addressed it is addressed SP-relative
(or, depending on the language and compiler, frame
pointer-relative). These data are of no further concern to this
specification.</li>
<li>Dynamically allocated data are created with malloc or new (or
whatever the language supports) and thereafter addressed indirectly
via pointers that may themselves be local, dynamically allocated,
or static. These data are of no further concern to this
specification.</li>
<li>Own, static, or extern data (terminology varies) are statically
allocated to memory. The allocation is done partly at compile time
and partly at static link time. It does not change during the
execution of the program. We shall use the term own data to
encompass C/C++ static, function-local static, and extern data that
the compiler does not allocate to a register. (Advanced compilers
can sometimes allocate C/C++ static data to registers).</li>
</ul>
<p>The rest of this section about ABI-supported addressing modes is
about addressing own data and functions.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="static-extern-imported-and-exported">
<h5>Static, extern, imported, and exported</h5>
<p>Among own data, languages and execution environments distinguish
between static, extern, imported, and exported. These categories
are not entirely independent, and the meaning of imported and
exported depends on the execution environment.</p>
<ul>
<li>Static data are local to a compilation unit (or to a function
within a compilation unit). A (2-pass) compiler can always see the
definition of a static datum.</li>
<li>Extern data are visible between compilation units. In general,
one compilation unit defines a datum and others refer to it. In
general, a reference to an extern datum cannot be bound until
static link time (or later). The compiler making the reference
cannot know where the data will be allocated.</li>
<li>Some extern data definitions and some function definitions may
be exported. That is, they may be visible to, and referenced from,
another static link unit (another executable, DLL, DSO, or shared
library).</li>
<li>Some extern references may be imported. That is, they refer to
definitions from another static link unit</li>
</ul>
<p>Import affects addressing because the location of an imported
entity is unknown to the static linker. In some cases, a compiler
must generate different code to address imported entities (<a href="index.html">ABI supported indirect addressing</a>).</p>
<p>Import and export can be explicitly described (as is typical in
DLL-based environments) or implicit, implied by extern, (as, by
default, in SVr4-based environments).</p>
<p>Explicit export and import are usually mutually exclusive.
Nevertheless, an exported entity may need to be treated as if it
were imported into the exporting link unit. See <a href="index.html">Absolute addressing and SVr4 (Linux)
application code</a> and <a href="index.html">Dynamic
resolution of vague linkage</a> for justification.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="shared-libraries-and-applications">
<h5>Shared libraries and applications</h5>
<p>At its simplest, a program consists of some application code
written by a user, statically linked with some library code
provided with the development tools and/or the execution
environment. In this model a program might interact with the
execution environment in a limited way - for example by executing
trap instructions or calling OS entry points at fixed addresses -
but it is essentially self sufficient.</p>
<p>more sophisticated model makes some or all of the library code
into dynamically loadable binaries (shared libraries), and the
application code into an application binary or executable.</p>
<p>Each executable and shared library file is built from some
translation units. Some extern references between translation units
which in the simple, single-binary program model were resolved
statically can no longer be fixed by the static linker. A dynamic
linking phase is needed before the program starts executing, to
resolve those references.</p>
<p>Note that this model can still be used to construct a standalone
(self sufficient) program by performing the dynamic linking off
line (in effect in a second, later phase of static linking). This
is necessary to create the ROM image of a system that can
dynamically load components but that carries some of them in
ROM.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="comparing-the-dso-and-dll-library-models">
<h5>Comparing the DSO and DLL library models</h5>
<p>The SVr4 model attempts to maintain precisely the same
environment for application relocatable objects whether they are
linked statically with their libraries or dynamically with DSOs
containing library code. By default, all extern entities are
imported and exported unless the producing tool chain is told
otherwise (by Q-o-I means). In general, programmers do not need to
be aware of import and export issues.</p>
<p>In contrast, DLL models usually make import and export explicit
and partition the set of extern entities into imported references,
exported definitions, and hidden definitions (local to the DLL or
application, but not local to a translation unit). Depending on the
design of the execution environment, a programmer might need to be
aware of import and export.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="abi-supported-direct-addressing-modes">
<h4>ABI supported direct addressing modes</h4>
<div>
<div>
<div>
<div id="absolute-addressing">
<h5>Absolute addressing</h5>
<p>The simplest way to address an extern entity is absolutely, via
an address constant. For example:</p>
<table>
<colgroup>
<col width="36%"/>
<col width="64%"/></colgroup>
<tbody valign="top">
<tr>
<td>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>extern int X;
int f(void)
{
  return X;
}
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
<td>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>   LDR   r0, LX       ; &amp;X
   LDR   r0, [r0, #0] ; X
   BX    lr
LX DCD   X
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<p>The address constant at LX points to the extern entity X. It is
given its value by a static linker. The address constant itself is
addressed PC-relative but a compiler will ensure that it is
generated close enough to the load.</p>
<p>(If we wanted to be pedantic we might describe this as short
PC-relative RO-indirect).</p>
<p>In general, this is the most efficient form of static data
addressing supported by the Arm architecture, but there are
difficulties with it.</p>
<ul>
<li>If X is imported rather than extern - so the address constant
cannot be relocated at static link time - this mode of addressing
will require the read-only segment to be relocated on being
loaded.</li>
<li>If several processes map the same instance of this code, each
process must allocate its copy of X at the same address (because
they all share the same pointer to X at LX).</li>
</ul>
<p>Note that absolute references work uniformly for both writable
data and read-only data.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="absolute-addressing-and-svr4-linux-application-code">
<h5>Absolute addressing and SVr4 (Linux) application code</h5>
<p>SVr4 application code uses absolute addressing and a trick to
avoid the need to relocate the RO segment.</p>
<p>When an application is linked against a shared library that
defines a datum used by the application (X, say), the linker
allocates space for X in the application's zero-initialized
(dot-bss) memory and resolves the application's references to
extern X to the application's definition of X. It then subjects
this definition to a dynamic, copy relocation. At dynamic link
time, the value of X will be copied from the DSO that defined it
into the application, and the DSO's reference to X will be linked
to the application's definition (the DSO's definition will be
pre-empted).</p>
<p>From the perspective of a DSO, an exported datum (X) must be
addressed as if it were imported, because if a definition is
provided by an application, that is exactly what will happen.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="absolute-addressing-windows-like-symbian-os-code-and-standalone-code">
<h5>Absolute addressing, Windows-like (Symbian OS) code, and
standalone code</h5>
<p>Windows-like DLL models - in particular, Symbian OS - use
absolute addressing in both applications and DLLs (but see also
<a href="index.html">How DLLs and their applications
address imported data</a>).</p>
<p>Absolute addressing is the preferred choice for standalone
(RTOS-based) applications.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="sb-relative-addressing-palm-os-like">
<h5>SB-relative addressing (Palm OS-like)</h5>
<p>SB-relative addressing supports shared libraries in a single
address space. The simple version of it is structurally similar to
absolute addressing. The writable static data associated with a
shared library is addressed using an offset from a dedicated static
base register (see [<a href="https://developer.arm.com/docs/ihi0042/latest">AAPCS</a>]). For
example:</p>
<table>
<colgroup>
<col width="35%"/>
<col width="65%"/></colgroup>
<tbody valign="top">
<tr>
<td>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>extern int X;
int f(void)
{
  return X;
}
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
<td>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>    LDR   r0,LX      ; &amp;X - SB
    ADD   r0,r0,sb   ; &amp;X
    LDR   r0,[r0,#0] ; X
    BX    lr
LX  DCDO  X
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<p>Here, the offset of X from SB is loaded short PC-relative from
the literal pool. The offset of data defined by the application or
shared library can be fixed at static link time, though, in
general, it needs to be re-based when the executable file is first
loaded.</p>
<p>References to imported data can be handled the same way if the
operating system preserves the invariant that the offset of a
library's static data from SB is the same in every process that
threads the library. This is effectively the same constraint that
Windows DLLs have, but on the offsets of data from SB rather than
on the addresses of data.</p>
<p>More complex versions of SB-relative addressing are possible
that formulate an offset from SB in a sequence of instructions. For
example, for offsets smaller than 20 bits, the above code could be
re-written as:</p>
<table>
<colgroup>
<col width="30%"/>
<col width="70%"/></colgroup>
<tbody valign="top">
<tr>
<td>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>extern int X;
int f(void)
{
  return X;
}
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
<td>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>ADD   r0, sb, #:SB_OFFSET_19_12: X
LDR   r0, [r0, #:SB_OFFSET_11_0: X
BX    lr
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<p>However, this complicates relocation of the read-only segment at
load time. In general, systems prefer to use only simple dynamic
relocations (for example, relocations of 32-bit data
locations).</p>
<p>An offset from SB implicitly addresses a writable location and
it will need to be relocated dynamically if it is used to address a
read-only place. (Recall, the DLL model gives independently chosen
base addresses to the read-only and read-write segments of the
executable file). In practice that encourages references to be made
as follows.</p>
<table id="id4">
<caption>Table 1, Inter-segment addressing in DLLs using
SB-relative addressing</caption>
<colgroup>
<col width="11%"/>
<col width="51%"/>
<col width="38%"/></colgroup>
<tbody valign="top">
<tr>
<td>
<p><strong>From</strong></p>
<p>To</p>
</td>
<td><strong>Read-only</strong></td>
<td><strong>Read-write</strong></td>
</tr>
<tr>
<td>Read-only</td>
<td>PC-relative (<a href="index.html">PC-relative
addressing (SVr4 DSOs)</a>) or Absolute</td>
<td>Absolute (<a href="index.html">Absolute
addressing</a>)</td>
</tr>
<tr>
<td>Read-write</td>
<td>SB-relative (this section)</td>
<td>Absolute</td>
</tr>
</tbody>
</table>
<p>Of course, the absolute addresses here require dynamic
relocation.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="pc-relative-addressing-svr4-dsos">
<h5>PC-relative addressing (SVr4 DSOs)</h5>
<p>An SVr4 (Linux) DSO can be mapped at a different virtual address
in each process that uses it. Writable data is at a fixed offset
from the code (a DSO has only one independent base address) so it
can be addressed relative to the current place. For example:</p>
<table>
<colgroup>
<col width="32%"/>
<col width="68%"/></colgroup>
<tbody valign="top">
<tr>
<td>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>static int X;
int f(void)
{
  return X;
}
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
<td>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>   LDR   r0, LX     ; &amp;X - (P + 8)
P  ADD   r0,pc,r0   ; &amp;X
   LDR   r0,[r0,#0] ; X
   BX    lr
LX DCD   |X + (LX - P - 8) - .|
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<p>In general, an imported datum X will be at a different address
in each process, and it can be at a different relative address (see
<a href="index.html">Own data addressing by SVr4
(Linux) DSOs and applications</a>), so there is no sharable offset
to it. Because of this, each potentially imported datum must be
addressed PC-relative indirect, via a writable location that can be
relocated when the DSO is loaded.</p>
<p>The SVr4 ABI calls the set of such locations the Global Offset
Table (GOT), and we call this addressing style GOT-relative.</p>
<p>As we noted above, every extern datum defined by a DSO is also
potentially imported because of potential pre-emption at dynamic
link time.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="abi-supported-indirect-addressing">
<h4>ABI supported indirect addressing</h4>
<p>The indirect addressing modes use one of the direct addressing
modes to address a pointer that can be initialized at dynamic link
time. The effect is as if the code on the left had been written as
the code on the right:</p>
<table>
<colgroup>
<col width="47%"/>
<col width="53%"/></colgroup>
<tbody valign="top">
<tr>
<td>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>extern Thing theThing;
// ...
// ...
Thing t = theThing;
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
<td>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>extern Thing theThing;
Thing* pThing = &amp;theThing;
// ...
Thing T = *pThing;
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<p>Whatever the primary addressing mode, the indirection is always
absolute via an address (using an offset would always be less
efficient at run time and would eliminate no dynamic
relocations).</p>
<div>
<div>
<div>
<div id="own-data-addressing-by-svr4-linux-dsos-and-applications">
<h5>Own data addressing by SVr4 (Linux) DSOs and applications</h5>
<p>As noted above, use of PC-relative indirect (SVr4 GOT-relative)
addressing modes follows from two choices.</p>
<ul>
<li>An SVr4 DSO has a single base address (its RW segment is at an
offset from its RO segment that was fixed when the DSO was
statically linked).</li>
<li>An SVr4 DSO can be loaded at a different virtual address in
each process that loads it.</li>
</ul>
<p>So although there is an invariant offset from any place in the
RO segment to own data that is not imported, there is no invariant
offset to any imported data.</p>
<p>As noted earlier, SVr4 does not make export and import explicit,
and chooses that application code should be oblivious to whether it
is linked statically or dynamically to its library code. These
decisions make all extern data used by a DSO potentially imported
and, therefore, to be addressed PC-relative indirect.</p>
<p>For SVr4, we can make some clear statements independent of
further considerations.</p>
<ul>
<li>Application code addresses its own data absolutely and calls
non-imported functions PC-relative.</li>
<li>Application code calls imported functions via a procedure
linkage stub generated by the static linker.</li>
</ul>
<div>
<div>
<div>
<div>
<div>(An imported function is simply one not defined by the
application).</div>
</div>
</div>
</div>
</div>
<ul>
<li>DSO addresses static and restricted visibility data PC-relative
and extern data PC-relative indirect.</li>
<li>A DSO calls static functions PC-relative and extern functions
via a procedure linkage stub generated by the static linker. The
stub calls indirectly through a writable function pointer (the
PLTGOT entry).</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="how-dlls-and-their-corresponding-applications-address-not-imported-data">
<h5>How DLLs and their corresponding applications address
not-imported data</h5>
<p>The DLL model preserves the invariant that each process
threading an instance of a DLL's RO segment maps its RW segment at
the same virtual address (or the same offset from SB if there is
only one address space). If this cannot be maintained when another
process P threads the DLL, P must load a new instance of the RO
segment.</p>
<p>A significant difference between a DLL and an application that
uses it is that when there are multiple virtual address spaces, the
execution addresses of the segments of an application can be known
at static link time, whereas a DLL (and a single address space
application) might need to be relocated dynamically.</p>
<ul>
<li>
<p>Multiple address space DLLs and application code
address local own data absolutely.</p>
<p>Address constants embedded in a DLL's RO segment must be
relocated when the segment is first loaded.</p>
</li>
<li>
<p>Single address space DLLs and application code
address local own data SB-relative.</p>
<p>The offsets from SB embedded in a DLL's RO segment must be
relocated when the segment is first loaded.</p>
</li>
<li>
<p>DLL and application code calls DLL-local functions
PC-relative.</p>
</li>
</ul>
<div>
<div>
<div>
<div>
<p>Note</p>
<p>To avoid relocating the RO segment of a single
address space application on first loading, some offset from SB
must be reserved to applications - analogous to reserving fixed
base addresses for multiple VA applications.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="how-dlls-and-their-applications-address-imported-data">
<h5>How DLLs and their applications address imported data</h5>
<p>The DLL model per se - whether deployed in a single address
space Palm OS-style, or multiple address spaces in the style of
Symbian OS or Windows - neither requires nor forbids indirect
addressing of imported data. Three factors influence a platform's
choice.</p>
<ul>
<li>The management of multiple processes (an OS
consideration).</li>
<li>Whether or not a DLL loaded into RAM can patch a collection of
DLLs in ROM (a platform consideration).</li>
<li>Whether or not the system can resolve vague linkage at dynamic
link time.</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="imported-data-and-the-management-of-multiple-processes">
<h5>Imported data and the management of multiple processes</h5>
<p>Depending on how the operating system manages the address space
of a process, it might be possible for process P1 to have mapped
DLL-1's RW segment at A1, and for process P2 to be unable to map it
there. P2 will subsequently create a copy of DLL-1's RO segment and
map a copy of the data of DLL-1 at A2.</p>
<p>Now consider the case that P1 and P2 both load DLL-2 that
imports X from DLL-1.</p>
<p>If X is addressed directly via a (dynamically relocated) literal
L in the read-only segment, L must be relocated to two different
values, A1 and A2 (which is impossible).</p>
<p>There are three ways a DLL-based OS can deal with this
problem.</p>
<ul>
<li>It can ensure that a DLL's address space slots are reserved in
all (future) processes. This enforces the data address invariant
globally and ensures that there is only one copy of the RO segment
of a DLL in the system.</li>
<li>It can accept that when more than one instance of a DLL has
been created, separate instances of all referring DLLs must be
created.</li>
<li>It can insist that imported data be addressed indirectly (as MS
Windows does), allowing one instance of DLL2 to refer via its P1
and P2 data instances to P1's DLL-1 or P2's DLL-1.</li>
</ul>
<p>Real DLL-based systems employ a combination of these strategies.
For example, Symbian OS currently uses the first two, but not the
third, while Palm OS currently uses the first and third, but not
the second.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="imported-entity-addressing-and-rom-patching">
<h5>Imported entity addressing and ROM patching</h5>
<p>Suppose that DLL-2 imports a function F and data X from DLL-1,
and suppose that both DLLs have been committed to ROM. Now suppose
that DLL-1 must be patched by loading a new version into Flash or
RAM.</p>
<p>For this to be effective, DLL-2 must be made to refer to the new
version of DLL-1 without changing any part of DLL-2. This can only
be done if the linkage between DLL-2 and DLL-1 is via writable RAM
locations. In effect all imported entities must be addressed
indirectly via RAM.</p>
<p>An SVr4 DSO already does this. Every extern entity with normal
visibility is addressed via a (writable) GOT entry. Even a
procedure linkage stub (PLT entry) must do this (via its PLTGOT
entry).</p>
<p>A DLL might be required do this, or it might not (<a href="index.html">How DLLs and their applications address
imported data</a>). However, to support being patched, a DLL too
must address imported entities indirectly.</p>
<p>Because the DLL model does not import and export extern entities
by default, indirect addressing forces import of data to be made
explicit at translation time (because different code must be
generated to access imported data), or it restricts import to
import by address (effectively making the indirection explicit in
the source code).</p>
<p>(Aside: The effect on the import of functions is less visible
because a procedure linkage stub is usually generated by the
linker. As far as a compiler is concerned, every extern function is
potentially imported. If a linkage stub must be hand written it is
also easy to arrange that import is by address initializing a
writable location - in effect, the PLTGOT model. End aside).</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="dynamic-resolution-of-vague-linkage">
<h5>Dynamic resolution of vague linkage</h5>
<p>RTTI, v-tables, and other entities generated by translating C++
pose a potential problem because, in general, there is no unique
locus of definition. For example, if a class has no key function,
RTTI and v-tables must be generated everywhere they are used
(according the C++ ABI for the Arm Architecture [<a href="https://developer.arm.com/docs/ihi0041/latest">CPPABI</a>], which,
in this respect, follows the Generic C++ ABI for Itanium [<a href="http://itanium-cxx-abi.github.io/cxx-abi/abi.html">GCPPABI</a>]).
These entities have vague linkage.</p>
<p>After translation, each such definition is wrapped in GRP_COMDAT
section group. A static linker retains only one copy, but a dynamic
linker can encounter multiple definitions, one from each shared
object. This is harmless if:</p>
<ul>
<li>All participants in the dynamic link step end up using the same
definition of each entity.</li>
<li>Or, the implementation of the One Definition Rule (ODR) does
not require a unique address for each entity.</li>
</ul>
<p>To guarantee a unique address, an entity with vague linkage must
be treated as both exported by, and imported into, each executable
file that defines it. Each defining file must be able to defer to
(be preempted by) another's definition at dynamic link time.</p>
<p>The problem of resolving dynamic vague linkage is depicted in
Figure 3, below. The illustrative scenario is based on C++ run-time
type information (RTTI). It arises naturally and frequently in
programs written in C++ but the problem is by no means restricted
to programs written in C++, or to RTTI.</p>
<ul>
<li>DLL-B contains the definitions relevant to class B (which has a
key function) and class A (which does not).</li>
<li>DLL-C similarly contain class C's definitions (and, again,
class C has a key function), and class A's.</li>
</ul>
<p>Both DLL-B and DLL-C export RTTI for class A. In a relocatable
file, RTTI for class A is emitted into a COMDAT group, and in a
static link step involving classes B and C, only one copy of the
RTTI for class A would be retained.</p>
<p>There are three possible use cases for DLL-B and DLL-C in
relation to RTTI-A.</p>
<ul>
<li>Process 1Link program B (that uses classes A, B) with
DLL-B.</li>
<li>Process 2Link program C (that uses classes A, C) with
DLL-C.</li>
<li>Process 3Link program BC (that uses classes A, B, C) with DLL-B
and DLL-C.</li>
</ul>
<p>Processes 1, 2, and 3 can execute simultaneously as depicted
below.</p>
<div class="documents-docsimg-container" id="id5"><img alt="bpabi32-dynamic-linkage-problem.png" src="bpabi32-dynamic-linkage-problem.png"/>
<p>Figure 3, The dynamic vague linkage problem</p>
</div>
<p>The One Definition Rule (ODR) for process 3 requires that all
users of the RTTI-A should use the same copy of it. In the static
link step generating program BC, the linker knows that references
to RTTI-A must resolve to DLL-C::RTTI-A, say. (It could choose
DLL-B::RTTI-A, but the argument is symmetrical).</p>
<p>Now there is a problem in process 1. References to RTTI-A from
DLL-B must resolve to DLL-B::RTTI-A (process 1 does not load DLL-C
so resolution to DLL-C::RTTI-A is impossible). Unless the reference
is private to the process, it must point to two different places in
two different processes (the dashed red pointer from DLL-B to
DLL-C::RTTI-A in process 3, and the solid black pointer from DLL-B
to DLL-B::RTTI-A in process 1).</p>
<p>If we want to resolve vague linkage dynamically, we must address
imported data indirectly via private-to-the-process locations.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="the-dll-model-and-indirect-addressing-of-imported-entities">
<h5>The DLL model and indirect addressing of imported entities</h5>
<p>Under the DLL model, indirect addressing goes hand in hand with
explicit data import. If imported data must be addressed
indirectly, a compiler must know what is imported so that it can
compile an extra indirection into the access code. A pseudo storage
class like __declspec(dllimport) is often used to tell a compiler
that an extern datum is imported.</p>
<p>Alternatively, and equivalently, import must be limited to
import by address used to initialize a writable pointer.</p>
<p>The following examples illustrate these points.</p>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>extern Thing* pThing;                 // (*pThing) can always be imported because pThing
                                      // is a writable pointer initialized by an address
extern Thing theThing;                // theThing cannot be imported if imported data
                                      // must be addressed indirectly
__declspec(dllimport) extern Thing T; // T is imported, and will be addressed
                                      // indirectly if this is required
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p>In general, imported functions do not need to be identified to a
compiler. A reference to an imported function will be made via a
procedure linkage stub created by a linker, so a compiler can
generate the same code for an imported call as for an extern call.
Under this ABI - and especially in Thumb state - it is not
generally beneficial to inline linkage stubs.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="summary-of-abi-addressing-modes">
<h4>Summary of ABI addressing modes</h4>
<p>The following tables list the addressing modes used by the
execution environments serving as exemplars for the platform
categories encompassed by this ABI.</p>
<table id="id6">
<caption>Table 2, Not imported (e.g. static) own data</caption>
<colgroup>
<col width="10%"/>
<col width="20%"/>
<col width="31%"/>
<col width="20%"/>
<col width="19%"/></colgroup>
<thead valign="bottom">
<tr>
<th rowspan="2">Ref to</th>
<th colspan="2">Single address space</th>
<th colspan="2">Multiple virtual address space</th>
</tr>
<tr>
<th>Bare platform</th>
<th>Palm OS DLL</th>
<th>Symbian OS DLL</th>
<th>Arm Linux DSO</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>RW</td>
<td>Absolute</td>
<td>SB-relative</td>
<td>Absolute</td>
<td>PC-relative</td>
</tr>
<tr>
<td>RO</td>
<td>Absolute</td>
<td>PC-relative or Absolute</td>
<td>Absolute</td>
<td>PC-relative</td>
</tr>
</tbody>
</table>
<table id="id7">
<caption>Table 3, Imported data referred to by not patchable
executable files</caption>
<colgroup>
<col width="9%"/>
<col width="16%"/>
<col width="27%"/>
<col width="17%"/>
<col width="31%"/></colgroup>
<thead valign="bottom">
<tr>
<th rowspan="2">Ref to</th>
<th colspan="2">Single address space</th>
<th colspan="2">Multiple virtual address space</th>
</tr>
<tr>
<th>Bare platform</th>
<th>Palm OS DLL</th>
<th>Symbian OS DLL</th>
<th>Arm Linux application</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>RW</td>
<td>Absolute</td>
<td>
<p>SB-relative</p>
<p><em>(non-standard)</em></p>
</td>
<td>Absolute</td>
<td rowspan="2">Absolute (copy relocated, patchable)</td>
</tr>
<tr>
<td>RO</td>
<td>Absolute</td>
<td>
<p>Absolute or PC-relative</p>
<p><em>(non-standard)</em></p>
</td>
<td>Absolute</td>
</tr>
</tbody>
</table>
<table id="id8">
<caption>Table 4, Imported own data referred to by patchable
executable files</caption>
<colgroup>
<col width="9%"/>
<col width="32%"/>
<col width="21%"/>
<col width="18%"/>
<col width="21%"/></colgroup>
<thead valign="bottom">
<tr>
<th rowspan="2">Ref to</th>
<th colspan="2">Single address space</th>
<th colspan="2">Multiple virtual address space</th>
</tr>
<tr>
<th>Bare platform with DLL structure</th>
<th>Palm OS</th>
<th>Symbian OS DLL</th>
<th>Arm Linux DSO</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>RO or RW</td>
<td>
<p>Absolute indirect</p>
<p><em>(non-standard)</em></p>
</td>
<td>SB-relative indirect</td>
<td>
<p>Absolute indirect</p>
<p><em>(non-standard)</em></p>
</td>
<td>PC-relative indirect</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="implications-of-the-one-definition-rule-for-execution-environments">
<h4>Implications of the one definition rule for execution
environments</h4>
<p>and C++ require that each data object and each function in a
program has a single definition. This is the One Definition Rule
(ODR). The ODR guarantees to a programmer that each addressable
object and function defined in the source program has a unique
address.</p>
<p>A static linker usually enforces the ODR by faulting multiple
definitions of the same symbol, or by discarding all but one
definition. This section examines the effect of the ODR on DLL and
DSO dynamic linkage.</p>
<div>
<div>
<div>
<div id="svr4-and-the-odr">
<h5>SVr4 and the ODR</h5>
<p>SVr4 application code need not be aware of whether it will be
linked statically or dynamically with the libraries it uses. In
effect, the dynamic linker must maintain the ODR the same way a
static linker does for entities local to an executable file.</p>
<p>It is easy to specify the treatment of data and clear that a
dynamic linker can easily enforce the ODR for data.</p>
<ul>
<li>
<p>A data definition exported by an application
pre-empts an identically named definition by a DSO.
Consequently:</p>
<ul>
<li>
<p>Application code can always use an absolute
address for an imported or exported datum.</p>
<p>(It is as if the imported datum is defined by the
application).</p>
</li>
<li>
<p>DSO code must always address imported/exported
data PC-relative indirect.</p>
</li>
</ul>
</li>
</ul>
<p>It is harder to specify the treatment of functions.</p>
<ul>
<li>All code must address imported functions PC-relative indirect
(via the [PLT]GOT).</li>
<li>DSO code formulating the address of an extern function can
simply load the corresponding [PLT]GOT entry. The dynamic linker
looks after its value.</li>
</ul>
<p>Application code can address an extern function F directly. If F
turns out to be imported, the only possible resolution of F at
static link time is to the PLT entry for F, generating two ugly
alternatives.</p>
<ul>
<li>
<p>The read-only segment of the application can be
dynamically relocated.</p>
<p>This is considered by SVr4 systems to be highly undesirable (in
any system in which applications might be shared between processes
there is a serious cost to the loss of sharing).</p>
</li>
<li>
<p>The dynamic linker can pre-empt the definition of
F with the application's PLT entry for F.</p>
<p>This is the standard Linux solution, but there are problems with
it.</p>
<ul>
<li>Calls through a function pointer initialized to F must now
indirect through a PLT entry.</li>
<li>To avoid calling via two PLT entries, the dynamic linker must
ensure that a PLTGOT entry for F points directly to F, not to the
application's PLT entry, and in any DSO that both calls F and takes
F's address there must be a separate GOT entry for F that points to
the application's PLT entry.</li>
</ul>
</li>
</ul>
<p>All calls to F (whether direct or indirect) traverse exactly one
PLT entry.</p>
<p>Alternatively, application code could take the address of a
function using absolute indirect (GOT-relative) addressing
(reducing import to import by address initializing a writable
location).</p>
<p>Of the two alternatives, the second is cleaner and has higher
performance, and taking the address of a function other than to
initialize an own-data function pointer is so rare that there is no
issue with the extra GOT entry.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="dlls-and-the-odr">
<h5>DLLs and the ODR</h5>
<p>The DLL model presents essentially the same difficulties as the
SVr4 model, but with some variations according to the taste of the
target platform.</p>
<ul>
<li>
<p>It is routine to relocate read-only segments on
first loading.</p>
<p>So, in the absence of resolving vague linkage dynamically, a DLL
can take the address of an exported entity or an imported entity as
if it were local to the DLL, and obtain the same address as any
other observer.</p>
</li>
<li>
<p>Usually, import and export are expressed
explicitly rather than being by default for all extern
entities.</p>
<p>So, if imported entities must be addressed indirectly, a
compiler can always know exactly to formulate the address of an
extern entity (for example, absolute-indirect if imported, absolute
otherwise).</p>
</li>
</ul>
<p>Under the usual explicit import and export model, preservation
of the ODR would follow from the discipline that only one DLL, or
the application, may define (export) an entity, and all others must
refer to (import) it.</p>
<p>As we discussed in <a href="index.html">Dynamic
resolution of vague linkage</a>, this is not possible for entities
with vague linkage. They have multiple definitions from which a
dynamic linker must choose one to impose program wide.</p>
<p>SVr4-based systems solve the resulting dynamic linking problem
straightforwardly because the dynamic linker looks up symbol names
while relocating an executable file. Pre-emption follows naturally
from the way the symbol table for a process is constructed.</p>
<p>In general, a DLL-based system must perform the required symbol
table juggling at static link time when the application that will
generate a process is created. This is the only point at which all
the DLLs to be linked into the process are known and symbol tables
are still available. By dynamic link time, otherwise global symbol
names will have been translated into DLL-local ordinal numbers, and
no process-wide symbol table will be built by the loader.</p>
<p>So, dynamic vague linkage must be resolved when an application
is created, and recorded in the resulting BPABI executable file in
a form that post-linkers can translate into platform-specific
dynamic relocation directives. This observation motivates the
specification given in <a href="index.html">Encoding
symbol pre-emption in BPABI executable files</a>.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="relating-executables-and-shared-objects-to-executable-files">
<h3>Relating executables and shared objects to executable
files</h3>
<div>
<div>
<div>
<div id="terminology">
<h4>Terminology</h4>
<p>[<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>]
already gives precise definitions to the words segment and section.
Section is not relevant to the executable view of an ELF file, so
it is not available for more general usage here. We use (program)
segment with its strict ELF meaning to denote a contiguous part of
an executable file read by a loader or dynamic linker. Where
segment explicitly or implicitly has type PT_LOAD, it refers a
contiguous part of an executable file loaded into memory to
initialize an executable image.</p>
<p>We also need a word to describe part of an executable image
loaded into virtual memory. We use the word region, familiar to
users of Arm development tools. An (execution) region contains the
minimum needed to support execution of the program on a bare
platform. A (program) segment usually contains one (execution)
region. On some platforms it also contains other platform-specific
data associated with loading or dynamic linking.</p>
<p>Finally, we need a term for part of an executable file that
serves a distinct, coherent purpose. We use the word component. A
segment is also a component. So is the content of a region when it
is stored in an executable file. On some platforms there are
components that are not part of any region or segment. Clearly, a
component can have sub-components.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="logical-content-of-an-executable-file">
<h4>Logical content of an executable file</h4>
<p>The figure below depicts a typical set of components present in
an executable file. Not all components are present in all
platform-specific formats, and the encoding of dynamic linking data
varies greatly between platforms. (The dynamic components shown in
the figure are a mélange of DLL and SVr4 components).</p>
<div class="documents-docsimg-container" id="id9"><img alt="bpabi32-exe-file.png" src="bpabi32-exe-file.png"/>
<p>Figure 4, Components of a typical executable
file and the relationships between them</p>
</div>
<p>Other than bare execution environments that do not load
executable files dynamically, the platforms of immediate interest
to this ABI base their executable file models directly or loosely
on the SVr4 executable file model or the Windows DLL/executable
file model.</p>
<div>
<div>
<div>
<div id="salient-features-of-svr4-executable-files">
<h5>Salient features of SVr4 executable files</h5>
<p>An SVr4 executable file has a dynamic symbol table to which
dynamic relocations refer. Imports and exports are neither
segregated nor tabulated separately from the symbol table.</p>
<p>procedure linkage table (PLT) - usually in the RO segment -
implements inter-file procedure linkage via function addresses
stored in a subsection of the global object table (GOT) called the
PLTGOT. The GOT is in the RW segment. It contains addresses of
global data and functions. It is initialized during dynamic
linking. In effect, the GOT is the import table, although it also
contains exported addresses and some addresses internal to the DSO
(depending on the details of how global symbol visibility was
controlled, if at all).</p>
<p>The RO segment includes RO regions from the dynamic components.
The RW segment includes all RW regions.</p>
<p>All file components required for dynamic linking and execution
are included in one of the (two) loaded segments.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="salient-features-of-windows-executable-files">
<h5>Salient features of Windows executable files</h5>
<p>A Windows executable file has no dynamic symbol table as such.
Imports and exports are separately tabulated and symbolic linkage
information is (optionally) attached to the export table and the
import table.</p>
<p>The RO segment usually includes all sharable, RO components. The
RW segment includes all RW regions.</p>
<p>All file components required for dynamic linking and execution
are included in one of the (two) loaded segments.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="executable-file-structure-static-linking-and-post-linking">
<h4>Executable file structure, static linking, and post
linking</h4>
<div>
<div>
<div>
<div id="linker-and-post-linker-roles">
<h5>Linker and post linker roles</h5>
<p>This base platform ABI defines a clear division of
responsibility for static linking between:</p>
<ul>
<li>A generic static linker of relatively high functionality and
complexity.</li>
<li>A platform-specific post linker of low complexity and
relatively low functionality.</li>
</ul>
<p>This division of responsibility is possible because we can find
standards that work across the platforms and executable file models
of interest to this ABI for at least the following.</p>
<ul>
<li>Required executable file components.</li>
<li>Name binding during linking.</li>
</ul>
<p>The primary role of a generic static linker is to create:</p>
<ul>
<li>The RO and RW execution regions.</li>
<li>Maximally symbolic (least bound to target platform) dynamic
components.</li>
</ul>
<p>Although conforming static linkers are generic to all execution
environments derived from this base platform ABI, and can generate
the same file components in the same order independent of the
target platform, some target-specific attributes must be built into
an executable file during the static linking step. Some parameters
and steering commands given to a generic static linker must,
inevitably, be specific to the target platform.</p>
<p>(Aside: This ABI only loosely constrains the order of components
in an executable file. ELF gives considerable freedom to place
content in almost any order [other than the ELF header, which must
be first]. End aside).</p>
<p>A post linker creates a platform-specific executable file if the
generic linker does not do so directly. A post linker is specific
to a target platform.</p>
<ul>
<li>It may not alter the RO or RW regions other than as described
by dynamic relocations (which it may process).</li>
<li>It may extend execution regions at their ends only, and then
only if a suitable address-space gap exists, or can be created,
between the regions.</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="executable-file-structure">
<h5>Executable file structure</h5>
<p>We observed in <a href="index.html">Simple post
linking</a> that of the concrete platforms this standard attempts
to encompass, Linux has the most symbolic executable file
format.</p>
<p><a href="index.html">Figure 5, SVr4 and base platform views
of the same executable file components</a>, below, depicts an SVr4
view and a BPABI view of the most important components of an
executable file.</p>
<ul>
<li>Both views start with a fixed size header (shown as the ELF
header) from which other sub-components of the file can be
found.</li>
<li>Both views contain a read-only executable segment followed by a
read-write data segment.</li>
</ul>
<p>In the SVr4 view, the RO segment contains in some order (the
order is conventional rather than essential):</p>
<ul>
<li>The ELF file header.</li>
<li>Directories of contents (shown as an array of ELF program
headers) that describe each component of the file, both in the file
and in virtual memory.</li>
<li>The read-only region of the program (the essence of what a
generic static linker producers).</li>
<li>The shareable dynamic linking components (dynamic linking RO
components).</li>
</ul>
<p>In the BPABI view of the same components the RO segment contains
only the RO execution region.</p>
<p>In the SVr4 view, the read-write component contains:</p>
<ul>
<li>The initialized read-write data region (the essence of what a
generic static linker produces).</li>
<li>Process-specific dynamic linking components (for Linux, at
least the GOT).</li>
</ul>
<p>In the BPABI view of the same components the RW segment contains
only the RW execution region.</p>
<div class="documents-docsimg-container" id="id10"><img alt="bpabi32-platform-views.png" src="bpabi32-platform-views.png"/>
<p>Figure 5, SVr4 and base platform views of the
same executable file components</p>
</div>
<p>In the execution environments abstracted by this ABI, the
read-write directory entry (RW program header) also describes the
zero-initialized (ZI or bss) execution region. It must immediately
follow the initialized RW region in virtual memory. This precludes
extension of the RW region by a post linker unless all references
from RO and RW to ZI are exposed via dynamic relocations.</p>
<p>Because an SVr4 DSO executable region must address its RW and ZI
regions pc-relative, a Linux executable is both rigid and compact
in virtual memory. This precludes extension of the RO segment by a
post linker unless all references from the RO region to RW and ZI
are exposed via dynamic relocations.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="interpretation-of-addresses-in-svr4-executable-files">
<h5>Interpretation of addresses in SVr4 executable files</h5>
<p>Virtual addresses are used to locate all structures in an SVr4
executable file.</p>
<p>SVr4 executable file is rigid and compact. It is designed to be
mapped into virtual memory, as described by its two PT_LOAD-type
program headers, and processed after mapping. There is one base
address for the executable file. If the file is a DSO, the base
address is unknown to the static linker and assumed by it to be
0.</p>
<p>All dynamic linkage data are included in one or other of the
loadable segments.</p>
<p>Because of the minimum granularity at which access to virtual
memory (VM) can be controlled (often 4, 8, or 64KB), there can be a
gap in VM between a file's loadable segments. Most SVr4 systems do
not represent the gap explicitly in the executable file (it would
be filled with zeroes). Consequently, an offset from the base
address in VM is not the same as an offset in the file (but the
PT_LOAD-type program headers describe how to convert between memory
offsets and file offsets).</p>
<p>A Dynamic Array address value is the address in virtual memory
after mapping at the assumed base address.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="interpretation-of-addresses-in-bpabi-executable-files">
<h5>Interpretation of addresses in BPABI executable files</h5>
<p>Virtual addresses are used to locate structures in the loadable
segments of an executable file. File offsets are used to locate
structures (such as dynamic linkage data) that are not part of any
loadable segment.</p>
<p>A base platform executable file has two (or more) loadable
segments and separate dynamic linkage data. It is designed to be
post processed to produce a file that can be loaded, linked
dynamically, and executed.</p>
<p>An address value that refers to a location in one of the
loadable segments is the virtual address of the location after
loading the segment into memory at its given base address. The two
PT_LOAD-type program segment headers describe how to translate such
virtual addresses to file offsets.</p>
<p>For the convenience of post linkers, an address that refers to
dynamic linkage data is the offset in the executable file of that
data. A post linker may later translate this to an address in
memory.</p>
<p>Consequently, some Dynamic Array address values are addresses in
virtual memory after mapping at the segment base addresses and some
are file offsets.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="base-platform-static-linking-and-post-linking">
<h3>Base platform static linking and post linking</h3>
<p>This section gives an overview of the division of responsibility
between generic static linking and post linking for the specific
platform operating systems of greatest influence on this
standard.</p>
<div>
<div>
<div>
<div id="arm-linux-and-similar">
<h4>Arm Linux and similar</h4>
<p>We expect that there will be no post linking to do.</p>
<p>If post linking were used, its only purpose would be to generate
the GOT from extended dynamic relocations. This functionality can
be more conveniently integrated into, and provided as an option by,
a static linker that otherwise targets the base platform ABI.</p>
<p>In summary, when given appropriate steering options, a generic
static linker must generate the following.</p>
<ul>
<li>The file components and an ELF view of them similar to that
depicted in blue in the upper half of <a href="index.html">Figure 5, SVr4 and base platform views of the same
executable file components</a>.</li>
<li>PLT (and other intra-call veneer) entries, position independent
if the executable file is a DSO.</li>
<li>All GOT entries (only these would be created by post linking if
a post linker were used).</li>
<li>Dynamic relocations (as defined by [<a href="https://developer.arm.com/docs/ihi0044/latest">AAELF</a>]), a full
dynamic symbol table, and symbol version data.</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="symbian-os-and-palm-os-dlls">
<h4>Symbian OS and Palm OS DLLs</h4>
<div>
<div>
<div>
<div id="generic-static-linker">
<h5>Generic static linker</h5>
<p>Appropriate steering options must be specified to the generic
static linker. That linker must generate:</p>
<ul>
<li>The same file components as for an SVr4 executable file, and an
ELF view of them, describing the RO region and the RW + ZI region,
similar to that depicted in red in the lower half of <a href="index.html">Figure 5, SVr4 and base platform views of the same
executable file components</a>.</li>
<li>Appropriate procedure linkage veneers ([not] PI, and direct, or
PLTGOT-indirect, as specified by linker option).</li>
<li>An extended set of dynamic relocations, a full dynamic symbol
table, and symbol version data.</li>
</ul>
<p>The type of the procedure linkage veneers depends on the target
platform.</p>
<ul>
<li>
<p>If a DLL is to be ROM-resident and its imported
references are to be patchable, or the target system wishes to
resolve vague linkage dynamically, the static linker must generate
procedure linkage veneers that are relocated by GOT-generating
relocation directives.</p>
<p>(Aside: Imported data references must be relocated by
GOT-generating relocation directives, but this must have been done
by the compiler because different code must be generated to address
imported data indirectly. End aside).</p>
</li>
<li>
<p>Otherwise, the generic static linker should
generate procedure linkage veneers that are relocated directly with
respect to their imported symbols.</p>
<p>(Aside: References to imported data are then no different to
references to extern data. End aside).</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="platform-specific-post-linker">
<h5>Platform-specific post linker</h5>
<p>The platform-specific post linker is responsible for:</p>
<ul>
<li>Translating symbolic references to ordinal-based (or other
platform-specific) references, and ensuring the integrity and
long-term validity of this translation.</li>
<li>Adding an export table and, if required, import tables.</li>
<li>Translating ELF relocation directives into the
platform-specific relocation format.</li>
<li>Reformatting the executable file and discarding symbolic
components unused by the platform.</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="translating-symbolic-references-to-ordinals-or-similar">
<h5>Translating symbolic references to ordinals (or similar)</h5>
<p>Somewhere the post linker must maintain a map must between
symbols and their platform-specific equivalents (as depicted in
<a href="index.html">Figure 2, Base platform ABI tool flow and
its relationship to concrete platforms</a>).</p>
<p>For Windows, the equivalent of a symbol is the ordinal number of
its entry in a DLL's export table, and this map has, traditionally,
been maintained in dot-def files, one per DLL.</p>
<p>It is logically equivalent to store this data in a section, with
OS- or processor-specific type ([<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>]
chapter 4, Sections) in the executable file itself, or to hold it
in a database specific to the platform.</p>
<p>If no corresponding map exists when a DLL is first post linked,
the post linker must create one.</p>
<p>The post linker must ensure consistency between the map and the
symbol table of the generic executable. For example, once an entry
point has been numbered, it cannot, in general, be renumbered.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="adding-export-and-import-tables-if-required">
<h5>Adding export and import tables (if required)</h5>
<p>Windows-style export table can be generated by post-processing
the dynamic symbol table. All defined STB_GLOBAL symbols whose
visibility is not restricted by STV_HIDDEN should be exported.
STB_WEAK is treated as equivalent to STB_GLOBAL for this
purpose.</p>
<p>Windows-style import tables can be generated by processing the
dynamic relocation section. Each [PLT]GOT-generating directive
generates an import table entry for the corresponding symbol. The
symbol's version data contains the identity of the DLL the symbol
is being imported from.</p>
<p>A single pass through the dynamic relocations can collate the
import data by DLL. It is then necessary to process each referenced
DLL's map entries (for example, its dot-def file) to convert each
imported symbol into an ordinal (its index in its import address
table) or similar.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="translating-elf-relocation-directives-to-platform-specific-form">
<h5>Translating ELF relocation directives to platform-specific
form</h5>
<p>A 32-bit-ELF relocation directive uses 8 bits to denote the
relocation type, 32 bits to denote the place being relocated, and
24 bits to select a 16-byte symbol with respect to which the
relocation is performed (which then points to a string value, the
name of the symbol).</p>
<p>Many space-saving optimizations are possible because, in
general, only 32-bit places can be relocated dynamically. Three
example schemes are listed below, in increasing order of
sophistication.</p>
<ul>
<li>If a naive indirect import table is used, no optimization is
necessary - the corresponding export table is simply copied during
dynamic linking. Such an import table can be placed at the end of
the ZI region.</li>
<li>Entries in an indirect import table can be initialized to the
indexes (ordinals) of the entries in the corresponding export
table. Such an import table must be placed at the end of the RW
region, and, In turn, this requires all references to ZI to be
relocated (as the ZI data will have been displaced).</li>
<li>If no import table is used dynamically, a relocation table can
list the places in this DLL to be patched by the dynamic loader.
The list can be compressed by, for example, storing only the
difference between consecutive offsets. Each place can be
initialized to, for example, the index in X's export table of the
required address value. The compact list of places can be placed
after the shared (RO) segment.</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="reformatting-the-executable-file">
<h5>Reformatting the executable file</h5>
<p>A post linker must do the following.</p>
<ul>
<li>
<p>Create a platform-specific file header and
directory structure.</p>
</li>
<li>
<p>Copy the RO region, and add generated RO
components such as the export table and direct import tables. In
general, there will be gap in the virtual address space between the
RO and RW segments, allowing the former to be extended at its end
without needing to relocate the latter.</p>
</li>
<li>
<p>Copy the RW region, and add generated RW
components such as initialized, indirect import tables.</p>
</li>
<li>
<p>Relocate references to ZI data by the amount it
extended the RW region. This can be done by processing the dynamic
relocation directives.</p>
<p>(Aside: In the RWPI procedure call standard variant [<a href="https://developer.arm.com/docs/ihi0042/latest">AAPCS</a>] - used
by Palm OS - this requires a static linker option to retain
appropriate static relocation directives in the dynamic relocation
section. End aside).</p>
</li>
<li>
<p>Adjust the ZI description and append any ZI import
tables to it.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="the-base-platform-abi-specification">
<h2>The Base Platform ABI Specification</h2>
<div>
<div>
<div>
<div id="scope-and-terminology">
<h3>Scope and terminology</h3>
<p>The subject matter of this specification is the following.</p>
<ul>
<li>The common, cross platform, static linker functionality needed
to make executable and shared object files for a wide variety of
specific platforms.</li>
<li>common, cross platform, file format from which simpler
platform-specific formats can be derived using simple post-linking
(discussed in <a href="index.html">Simple post
linking</a>).</li>
</ul>
<p>This specification is a necessarily compromise between
maximizing the utility of Base Platform executable files, and
minimizing the burden on their producers and consumers.</p>
<p>For a discussion of our use of the words segment, section,
region, and component, please see <a href="index.html">Terminology</a>.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="executable-file-format">
<h3>Executable file format</h3>
<p>The carrier file format is ELF with type ET_EXEC (for
application executable files) and ET_DYN (for DSO/DLL executable
files).</p>
<p>For information about ELF see [<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>].
Chapter 5 gives details relating to program loading and dynamic
linking referred to in the following subsections of this section.
Chapter 4 gives general details of ELF and its linking view. ELF
for the Arm Architecture [<a href="https://developer.arm.com/docs/ihi0044/latest">AAELF</a>]
specifies the processor-specific values used by Arm.</p>
<p>Only the executable (program segment) view features in this
ABI.</p>
<p>platform executable or dynamic shared object (DSO, DLL, or
shared library) file contains two loadable segments (described by
ELF program headers of type PT_LOAD).</p>
<ul>
<li>A read-only segment contains executable code and read-only
data. Its program header describes the segment as readable and
executable (PF_R + PF_X set).</li>
<li>A read-write segment contains initialized data and data
initialized to zero by the execution environment. Its program
header describes the segment as readable and writable (PF_R + PF_W
set).</li>
</ul>
<p>An executable file (of ELF type ET_EXEC) that cannot be loaded
dynamically (for example, that might execute from ROM) may contain
any number of executable segments described by ELF program headers
of type PT_LOAD.</p>
<p>No read-write segment shall contain executable code.</p>
<p>Each segment shall be contiguous in the address space and in the
ELF file.</p>
<p>Other ELF segment headers (of type PT_DYNAMIC, PT_INTERP,
PT_PHDR, etc) may be present or required by the target platform.
These describe components of the executable file of interest to
loaders and dynamic linkers. In general these segments are not
separately loadable.</p>
<ul>
<li>Under the SVr4 ABI, the corresponding file components are
included in the loadable segments and the program headers serve
only as directory entries to locate them in virtual memory.</li>
<li>Under this base platform ABI, the corresponding file components
are not included in any loadable segment. Their program headers
serve as directory entries to locate them in the executable
file.</li>
</ul>
<p><a href="index.html">Figure 5, SVr4 and base platform views
of the same executable file components</a> shows how a static
linker can describe the same file components in two different
ways.</p>
<div>
<div>
<div>
<div id="elf-header">
<h4>ELF header</h4>
<p>The ELF file header shall be mapped by a program header of type
PT_PHDR. The ELF file header shall be the first component of the
executable file at file offset 0.</p>
<p>Segment base addresses and alignments are target-specific. How
they are specified to a static linker is Q-o-I.</p>
<p>Loadable segments must be at least 8-byte aligned in order to
preserve alignment guarantees assumed by compilers complying with
the [<a href="https://developer.arm.com/docs/ihi0042/latest">AAPCS</a>].</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="the-dynamic-segment-and-its-related-sections">
<h4>The dynamic segment and its related sections</h4>
<p>The dynamic section shall be described by a program header of
type PT_DYNAMIC.</p>
<p><a href="index.html">Interpretation of addresses in
SVr4 executable files</a> and <a href="index.html">Interpretation of addresses in BPABI
executable files</a> explain the term address, mentioned repeatedly
in sub-sections of this section.</p>
<div>
<div>
<div>
<div id="the-dynamic-section">
<h5>The dynamic section</h5>
<p>The dynamic section contains an array of &lt;key, value&gt;
pairs that describe structures of interest to a dynamic linker.
([<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>],
Chapter 5, sub-section Dynamic Section. Table 5-10, Dynamic Array
Tags, lists mandatory entries).</p>
<p>The key in a &lt;key, value&gt; pair is an integer identifying
the purpose of the pair. ELF-defined keys have symbolic names
beginning DT_. Processor-specific keys defined by Arm have symbolic
names beginning DT_ARM_.</p>
<p>The value in a &lt;key, value&gt; pair may be an address or a
number such as a count or size.</p>
<p>All other sections related to dynamic linking shall be locatable
from the dynamic section.</p>
<ul>
<li>In an SVr4-style executable file these sections and the dynamic
section itself are included in one of the two loadable segments,
and addresses must be interpreted as described in <a href="index.html">Interpretation of addresses in SVr4
executable files</a>.</li>
<li>In a BPABI executable file these sections are excluded from the
two loadable segments, and addresses must be interpreted as
described in <a href="index.html">Interpretation of
addresses in BPABI executable files</a>.</li>
</ul>
<p>The dynamic section locates the dynamic symbol table, the hash
table and the dynamic relocation sections.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="dynamic-symbol-table">
<h5>Dynamic symbol table</h5>
<p>The dynamic symbol table is an ELF symbol table with the
following restrictions.</p>
<ul>
<li>It includes copies of just those symbols relevant to dynamic
linking (those with STB_GLOBAL binding, and any STB_LOCAL symbols
cited by a dynamic relocation [described below]).</li>
<li>The st_value field of each symbol is the presumed target
address set by the static linker (the linker must assume some
target address, even if the executable's loadable segments will be
dynamically relocated).</li>
</ul>
<p>The dynamic symbol table is located by the DT_SYMTAB entry in
the dynamic section.</p>
<p>No standard ELF dynamic section entry directly gives the size of
the symbol table, but its size is the same as that of the hash
table [described in the next sub-section] located by the DT_HASH
entry.</p>
<p>In a BPABI executable file, the Arm-specific tag DT_ARM_SYMTABSZ
gives the number of entries.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="hash-table">
<h5>Hash table</h5>
<p>The hash table is located by the DT_HASH entry in the dynamic
array. It has a bucket and chain organization, with one chain entry
for each entry in the dynamic symbol table.</p>
<p>The size of the dynamic symbol table is, therefore, given by the
hash table's nchain field. In a BPABI executable file, the value of
the Arm-specific tag DT_ARM_SYMTABSZ is also nchain.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="dynamic-relocation-section-s">
<h5>Dynamic relocation section(s)</h5>
<p>The dynamic section of an executable file (<a href="index.html">The dynamic section</a>) can
independently describe two relocation sections, one containing
relocations to be performed when a file is first loaded into a
process, and one containing procedure linkage relocations that can
be performed lazily, if the execution environment has that
capability.</p>
<p>In spite of this, it appears that the original intent of the
SVr4 ABI ([<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>])
was that the lazy procedure linkage relocations should be in a
subsection of the relocation section. Indeed, some ports of SVr4
appear to rely on the lazy relocations being a subsection at the
end of the relocation section.</p>
<p>This ABI strongly recommends that:</p>
<ul>
<li>Producers should produce a single, homogeneous (all REL-type or
all RELA-type), consolidated dynamic relocation section, with
procedure linkage (typically PLTGOT) relocations collated after all
others. This procedure linkage subsection should be described as
overlapping the relocation section.</li>
<li>Consumers should defensively analyze the descriptions given in
the dynamic section and be prepared to work with disjoint or
arbitrarily overlapping subsections, and with subsections that have
different REL/RELA-types.</li>
</ul>
<p>The dynamic relocation section is described by one of the
following triples of &lt;key, value&gt; pairs, depending of whether
REL-type or all RELA-type relocations are being used.</p>
<table>
<colgroup>
<col width="27%"/>
<col width="34%"/>
<col width="39%"/></colgroup>
<tbody valign="top">
<tr>
<td>DT_REL address</td>
<td>DT_RELSZ table-size</td>
<td>DT_RELENT element-size</td>
</tr>
<tr>
<td>DT_RELA address</td>
<td>DT_RELASZ table-size</td>
<td>DT_RELAENT element-size</td>
</tr>
</tbody>
</table>
<p>&lt;Key, value&gt; pairs may occur in any order in the dynamic
array.</p>
<p>(dynamic) relocation directive identifies a place to be
relocated via the address given in its r_offset field, and the
index of a symbol in the dynamic symbol table via its r_info
field.</p>
<p>Relocation sections in an SVr4 executable file shall only use
dynamic relocations (as defined in [<a href="https://developer.arm.com/docs/ihi0044/latest">AAELF</a>]).</p>
<p>Because it will be processed off line by a post linker, a
relocation section in a BPABI executable file may use any valid
relocation (and, in general, may need to use [PLT]GOT-generating
relocations).</p>
<p>subsection at the end of the relocation section should contain
the relocations relating to procedure linkage (typically PLTGOT
relocations). A platform ABI may specify its position in the
relocation section, and it may be processed lazily by a dynamic
linker. In a BPABI executable file this subsection is very
important to post linkers.</p>
<p>The procedure linkage subsection must be described by the
following triple of &lt;key, value&gt; pairs.</p>
<table>
<colgroup>
<col width="23%"/>
<col width="30%"/>
<col width="47%"/></colgroup>
<tbody valign="top">
<tr>
<td>DT_JMPREL address</td>
<td>DT_PLTRELSZ table-size</td>
<td>DT_PLTREL type (= DT_REL or DT_RELA)</td>
</tr>
</tbody>
</table>
<p>In the format strongly recommended by this ABI, address +
table-size gives the same end point for both the relocation section
and the procedure linkage subsection.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="shared-object-dll-name">
<h5>Shared object (DLL) name</h5>
<p>The dynamic section entry keyed by DT_SONAME gives the offset in
the dynamic string table of the name of a shared object (SVr4 DSO
or BPABI DLL). These names are cited by DT_NEEDED entries in other
executable files.</p>
<p>A shared object name is required for shared object executable
files (ELF type ET_DYN) that might be post-processed by a
platform-specific post linker.</p>
<p>The value of the shared object name is platform-specific.
Generic static linkers must provide an option (Q-o-I) to set it. If
not set by this Q-o-I means, a static linker must default the name
to the basename of the file name. For example, if the filename is
somewhereMyDLL.dll, the default shared object name should be
MyDLL.dll.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="symbol-binding-and-versioning">
<h3>Symbol binding and versioning</h3>
<div>
<div>
<div>
<div id="overview-of-common-static-linking-models">
<h4>Overview of common static linking models</h4>
<p>Each executable or shared object file is generated by a static
linking step in which a collection of relocatable files -
including, perhaps, some extracted from static libraries - are
linked to form the executable file.</p>
<p>In place of linking against a static library, you may instead
link against a previously linked executable file.</p>
<ul>
<li>Under Linux you can link against a previously linked dynamic
shared object (DSO).</li>
<li>Under Windows you can link against an import library
corresponding to a previously linked DLL.</li>
</ul>
<p>Historically, a Windows import library contained the import data
sections and linkage stubs - PLT entries in SVr4-terminology -
matching the export data section generated when the DLL was
created. It was a real library of relocatable object files. Today
these are called long format import libraries, and, in contrast,
short format import libraries contain only a few bits of
information about each exported symbol, its name, and the name of
the DLL exporting it. A linker can construct import data tables
from this summary, a synopsis of the data in the DLL it corresponds
to, but it could just as easily be extracted directly from the
exporting DLL, SVr4 style.</p>
<p>The advantage of a long format import library is that its use
requires no additional inbuilt linker functionality. It can be
generated independently of the linker, using simple tools (e.g.
using an assembler), and then the link step that generates a DLL is
then no different to any other link step. This tool flow also
inherently solves the problem of creating two DLLs that refer to
one another. One of them need to be linked first, but in the modern
flow neither can be! In the old flow, an import library for one of
the DLLs can be manufactured before the DLL is linked.</p>
<p>The SVr4 DSO-creating tool flow is structurally similar to the
Windows DLL-creating tool flow using short format import
libraries.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="the-relationship-between-binding-and-linking">
<h4>The relationship between binding and linking</h4>
<p>Executable and shared object files can contain references to
symbols defined elsewhere (imported symbols) and can export symbol
definitions to be used elsewhere. Dynamic linking matches the
symbols imported by an executable file to those exported by
previously loaded executable files.</p>
<div>
<div>
<div>
<div id="static-binding">
<h5>Static binding</h5>
<p>Under the static binding model, when a static linker creates an
executable or shared object file it knows which DSO/DLL will
resolve each imported symbol at dynamic link time. The binding of
references to definitions is fixed at static link time, even though
linking (converting symbolic references to addresses) is done
dynamically.</p>
<p>Static binding is used by:</p>
<ul>
<li>SUN Solaris and Linux in the presence of versioned
symbols.</li>
<li>Microsoft Windows, Palm OS , Symbian OS.</li>
</ul>
<p>Static binding is required to support non-symbolic dynamic
linking (such as DLL linking by ordinal).</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="dynamic-binding">
<h5>Dynamic binding</h5>
<p>Under the dynamic binding model, a static linker cannot know
which DSO/DLL will resolve an imported symbol at dynamic link time.
The binding of references to definitions is delayed until the link
is made.</p>
<p>Dynamic binding is used by SUN Solaris and Linux in the absence
of versioned symbols, and by older SVr4-based and other Unix
systems.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="this-abi-requires-and-supports-static-binding">
<h5>This ABI requires and supports static binding</h5>
<p>The symbols relevant to this specification are contained in the
dynamic symbol table of an executable file. Conventionally, the
dynamic symbol table is an ELF section of type SHT_DYNSYM and name
.dynsym.</p>
<p>Each symbol in the dynamic symbol table that has global binding
(STB_GLOBAL) is either imported or exported. Undefined symbols -
defined in the section with index SHN_UNDEF - are imported. Defined
symbols are exported.</p>
<p>Local symbols (with binding STB_LOCAL) can participate in
load-time relocation but play no part in binding.</p>
<p>As required generically by the ELF specification, the static
linker must ensure that symbols that have restricted visibility
(STV_HIDDEN, for example) in relocatable files are removed from the
dynamic symbol table, or converted to dynamic symbols with local
binding.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="symbol-versioning">
<h4>Symbol versioning</h4>
<p>This ABI adopts the GNU-extended Solaris symbol versioning
mechanism described in [<a href="https://developer.arm.com/docs/ihi0044/latest">AAELF</a>].</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="the-processing-of-symbols-and-versions-by-complying-static-linkers">
<h4>The processing of symbols and versions by complying static
linkers</h4>
<p>This section describes how a static linker must process symbols
and versions when creating a base platform executable file, DLL, or
DSO from a collection of relocatable files and previously linked
executable file.</p>
<div>
<div>
<div>
<div id="creating-version-definitions-for-symbols-exported-by-a-shared-library-dso-or-dll">
<h5>Creating version definitions for symbols exported by a shared
library (DSO or DLL)</h5>
<p>Version definitions are created when a shared object executable
file (ELF type ET_DYN) is statically linked. Plain executable files
(ELF type ET_EXEC) do not require version definitions.</p>
<p>The list of version definitions in an executable file
conventionally includes a first element with index 1 and flags
VER_FLG_BASE that gives the version of the shared object rather
than the version of any symbol within it.</p>
<p>typical Linux value of the base version might be "libm.so.6"
whereas the versions of the symbols defined in this library might
be "GLIB_2.0" or "GLIBC_2.1".</p>
<p>Version data for symbols exported from this executable file can
be provided in three ways.</p>
<ul>
<li>By linker steering file (Q-o-I).</li>
<li>Using the GNU mechanism to associate versions with symbol
definitions.</li>
<li>By default, perhaps further controlled by linker option, as
described in <a href="index.html">Option to support
forced static binding</a>.</li>
</ul>
<p>The essence of the GNU mechanism is that a symbol defined with a
particular version has the textual name name@[@]version.</p>
<ul>
<li>The form using '@@' denotes a default, or latest, version.
There must be exactly one such definition of name in a link step,
and this defines the version seen by subsequent static links
against this executable file.</li>
<li>The form using '@' defines a previous version of name. There
can be any number of previous versions, but these will only be seen
during dynamic linking. (These symbols will refer to their
corresponding versions via indexes with bit 15 set).</li>
</ul>
<p>There is no need to export any other STB_GLOBAL symbol defined
at the same location as an @-containing one.</p>
<p>The export of an STB_GLOBAL symbol from a relocatable file may
be restricted by using the STV_HIDDEN attribute. Hidden symbols are
not exported. If they need to be in the dynamic symbol table
because, for example, there are dynamic relocations that refer to
them, their binding must be changed to STB_LOCAL.</p>
<p>(Aside: In general, the use of STV_HIDDEN requires use of
additional build options and source level mechanism such as
__ATTRIBUTE__("STV_HIDDEN") or __declspec(dllexport) not specified
by this ABI. End aside).</p>
<p>Export may be further restricted, and import further extended,
through commands to the static linker (Q-o-I).</p>
<p>If a symbol X exported by this executable file has a version -
that is, its name is X@[@]version) - the linker must:</p>
<ul>
<li>Ensure that version is described by a version definition
structure in the version definition section.</li>
<li>Allocate an index in the virtual table of versions to each new
version definition.</li>
<li>Set the symbol version section entry corresponding to X to this
index of version.</li>
</ul>
<p>Indexes denoting <a href="mailto:X%40version">X@version</a> must
have bit 15 set. The index denoting X@@version must have bit 15
clear</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="creating-versions-needed-for-symbols-undefined-in-an-executable-file">
<h5>Creating versions needed for symbols undefined in an executable
file</h5>
<p>Versions needed are created when an executable file (ELF type
ET_EXEC or ET_DYN) is created in a static link step to which a
shared object executable file (ELF type ET_DYN) with versioned
symbols is an input.</p>
<p>versions needed structure must be created when this link step
uses a previously linked executable file, L say. The versions
needed structure names L (using L's SONAME) and links to auxiliary
structures. Each auxiliary structure describes the binding of a set
of symbols otherwise undefined in this link step to a corresponding
set of symbols defined by L which share a common version defined by
L.</p>
<p>If X is undefined in this link step and an input executable file
L exports a versioned definition of symbol X, the linker must:</p>
<ul>
<li>
<p>Ensure that this link step's versions needed
section contains a versions needed structure associated with the
SONAME of L.</p>
<p>(A needed executable file must also be named by a DT_NEEDED
entry in the dynamic section. A DT_NEEDED entry names the SONAME of
the executable file it refers to).</p>
</li>
<li>
<p>Ensure that the name of the version associated
with X is recorded in a version needed auxiliary structure linked
to the versions needed structure.</p>
</li>
<li>
<p>Allocate an index in the virtual table of versions
to each new versions needed auxiliary structure.</p>
</li>
<li>
<p>Set the symbol version section entry corresponding
to X to this index of version.</p>
</li>
</ul>
<p>If there are multiple versions of X defined, all but one of them
will refer to their versions via indexes with bit 15 set. In
effect, all but one of the definitions of X will be hidden from
static binding.</p>
<p>(Aside: In general it is only possible to bind statically to the
latest version of a symbol X exported by an executable file. Any
other tool chain behavior is Q-o-I. If the executable file
exporting X is subsequently updated creating a new version of X and
preserving the old version, this executable will nonetheless be
linked dynamically to the old version X. An attempt to link this
executable dynamically to a version of the DSO that does not export
the required version of X will fail. End aside).</p>
<p>Hence, via the symbol version section, each undefined symbol in
this link step simultaneously acquires a required version and an
executable file from which it is being imported.</p>
<p>(Aside: This representation gives an indirect encoding of the
information given by a DLL's import data section, namely where each
undefined symbol is imported from. End aside).</p>
<p>When linking for an SVr4-like platform it is acceptable for a
DSO not to export versioned symbols. In this case the index of the
corresponding version needed is 1, signifying that dynamic binding
must be used.</p>
<p>When linking for a DLL-based platform, a static linker must
force static binding as described below.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="option-to-support-forced-static-binding">
<h5>Option to support forced static binding</h5>
<p>An ABI complying static linker must provide an option to force
static binding.</p>
<ul>
<li>
<p>In a DLL-creating link step in which some exported
symbols have no version, a linker must create a default version.
The name of that version shall be the SONAME of the exporting
DLL.</p>
<p>In the common case that no exported symbol has a version, the
linker shall create a version definition with index 1 and flags
VER_FLG_BASE giving a version to the shared object itself, and a
clone of it with index 2 and flags 0 that shares the same auxiliary
structure. Each exported symbol definition shall be given version
index 2 in the versions section.</p>
</li>
<li>
<p>Optionally, a linker can create a default version
needed for each undefined symbol that binds to an imported
definition with no version. The name of the needed version shall be
the SONAME of the shared object imported from (that is, the default
version name for the symbol's definition).</p>
<p>This behavior supports creating mutually dependent shared
objects, should that be required.</p>
</li>
</ul>
<p>A linker should fault non-weak symbols that remain unbound at
the end of a DLL-creating link step. (If binding is static, there
can be no STB_GLOBAL symbol with no version).</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="relationships-among-versions-of-an-exported-symbol">
<h5>Relationships among versions of an exported symbol</h5>
<p>For the purpose of binding statically to an executable file,
there is one distinguished (default) version of each exported
symbol with a given name. Among all the exported symbols called X
exactly one refers to its version via an index with bit 15 clear.
All others refer to their versions via indexes with bit 15 set.</p>
<p>For the purpose of dynamically linking executable files,
relationships among versions of a symbol X, say, are immaterial. A
dynamic linker must link to the definition of X whose version
matches the needed version.</p>
<p>A Linux DSO represents the historical relationship among
versions using second and subsequent members of the vd_aux list to
record older versions, but this appears to be unused by both static
binding and dynamic linking.</p>
<p>This ABI imposes no requirement to represent a version history,
shown grayed in the figure below, in a base platform shared
object.</p>
<div class="documents-docsimg-container" id="id11"><img alt="bpabi32-two-versions.png" src="bpabi32-two-versions.png"/>
<p>Figure 6, How two versions of the same symbol
are represented in a Linux DSO</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="procedure-linkage-and-other-intra-call-veneers">
<h3>Procedure linkage and other intra-call veneers</h3>
<p>This section states the requirement on static linkers to
generate the intra-call veneers needed to implement calls between
separately loaded static link units (typically executable files,
and DSOs or DLLs).</p>
<p>Calls between sufficiently separated regions within a bare
platform executable generate similar requirements.</p>
<p>The ELF processor supplement [<a href="https://developer.arm.com/docs/ihi0044/latest">AAELF</a>] gives
examples of procedure linkage code sequences, and discusses
[PLT]GOT-generating relocation.</p>
<div>
<div>
<div>
<div id="overview-and-terminology">
<h4>Overview and terminology</h4>
<p>In general, an Arm-Thumb call (BL/BLX) instruction cannot reach
an arbitrary destination. The reach of BL is from 2<sup>22</sup> to
2<sup>26</sup> bytes, while the address space spans 2<sup>32</sup>
bytes.</p>
<p>An imported destination is certainly at an unknown range, so a
long-branch veneer (with 32-bit span) must be inserted between a
call site and an imported destination.</p>
<p>veneer may be needed if the instruction set state might change
between the site of a call and its destination. Sometimes this can
be accommodated by changing BL to BLX, but if the branch span is
large or there is no BLX instruction (Arm Architecture V4T), a
veneer (also called a PLT entry) will be required.</p>
<p>In linkage models in which the target address may be different
in each process threading the executable (SVr4 DSO), or the linkage
between ROM-resident executable files must be later patchable (e.g.
Palm OS), a veneer must call indirectly through a run-time writable
location private to the process.</p>
<p>Usually there is one veneer for each distinct destination code
symbol, shared between all callers within the same executable
region. In particular, there is one procedure linkage veneer (PLT
entry) for each imported code symbol shared by all callers from the
same executable file.</p>
<p>(Aside: Support for executable files containing larger than 4MB
Thumb-1 code regions is Q-o-I. End aside).</p>
<p>In SVr4-style tool chains there is a clear convention that a
static linker must generate veneers - called procedure linkage
table (PLT) entries - on calls to imported code symbols. The
writable location corresponding to an SVr4 PLT entry is called a
PLTGOT entry.</p>
<p>A similar convention of tools for the Arm-Thumb bare platform is
that a static linker must generate whatever veneer is needed
between the site of a call and its destination. The type of veneer
required depends on the Arm architecture version, the branch span,
and whether there is a change of instruction-set state.</p>
<p>The SVr4 convention combined with the Arm-Thumb bare platform
convention strongly suggests that static linkers must generate
intra-call veneers whenever they are needed (<a href="index.html">Code generation for intra-call veneers (PLT
entries)</a>).</p>
<p>In the SVr4 DSO linkage model the PLTGOT must be an array of
equal sized elements, and there is a hidden relationship between
the order of the entries in it and the order of relocation entries
referring to it.</p>
<p>In the Windows DLL linkage model, PLTGOT entries must be
collated by DLL imported from and they are not necessarily
contiguous, being potentially interspersed with other (data)
addresses imported from the same DLL.</p>
<p>This ABI deals with the difference between DSO behavior and DLL
behavior via relocation directives. In both cases, a location in
the PLT is relocated by one of a family of GOT-generating
relocation directives. A static linker can choose (Q-o-I):</p>
<ul>
<li>To process such directives in a target-specific manner, thereby
generating a target-specific executable file.</li>
<li>To leave such directives as dynamic relocations to be processed
by a target-specific post-linker.</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="code-generation-for-intra-call-veneers-plt-entries">
<h4>Code generation for intra-call veneers (PLT entries)</h4>
<div>
<div>
<div>
<div id="general-remarks">
<h5>General remarks</h5>
<p>This ABI does not specify code sequences to be used for
intra-call veneers. Any code sequence that meets the constraints of
the ABI and achieves the required effect may be used. The ELF
processor supplement [<a href="https://developer.arm.com/docs/ihi0044/latest">AAELF</a>] gives
some specimen sequences, all of which are usable.</p>
<p>The following are explicitly quality of implementation (Q-o-I)
concerns.</p>
<ul>
<li>The generation of optimal veneers. (This is a complex,
target-specific, business).</li>
<li>The generation of veneers to extend the (usually Thumb-state)
BL span within a single execution region. (There is no obvious
place - such as at the end of the region - for a linker to place
such veneers).</li>
</ul>
<p>The following observations might be useful to authors of
intra-call veneers.</p>
<ul>
<li>
<p>Under the Procedure Call Standard for the Arm
Architecture [<a href="https://developer.arm.com/docs/ihi0042/latest">AAPCS</a>],
register ip (r12) is the only scratch register available to a
veneer or PLT entry.</p>
</li>
<li>
<p>Under Arm architecture version 5 and later, an
unconditional BL and a BLX can be inter-converted (removing the
need for a state-changing veneer).</p>
</li>
<li>
<p>Under Arm architecture version 5 and later, any
kind of load to the pc sets the instruction set state to the least
significant bit of the loaded address (1 → Thumb state, 0 → Arm
state).</p>
</li>
<li>
<p>Under Arm architecture version 4T, only BX changes
the instruction set state. In effect, a V4T state-changing veneer
must end with <code>LDR ip, [...]; BX ip</code>.</p>
</li>
<li>
<p>In Thumb state, <code>ALIGN 4; BX pc; NOP</code>,
causes entry into Arm state.</p>
</li>
<li>
<p>linker may be required to generate
position-independent veneers and/or veneers whose read-only
sections are free of dynamic relocations (SVr4 DSO, at least).</p>
</li>
<li>
<p>When the platform supports lazy function binding
(as Arm Linux does) this ABI requires ip to address the
corresponding PLTGOT entry at the point where the PLT calls through
it.</p>
<p>(The PLT is required to behave as if it ended with <code>LDR pc,
[ip]</code>).</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="plt-relocation">
<h5>PLT relocation</h5>
<p>A post linker may need to distinguish PLTGOT-generating
relocations from GOT-generating ones.</p>
<p>If a static linker were generating a relocatable ELF file it
would naturally generate the PLT into its own section (.plt, say),
subject to relocations from a corresponding relocation section
(.rel.plt say). No other GOT-generating relocations can occur in
.rel.plt, so that section would contain all the PLTGOT-generating
relocations.</p>
<p>This ABI requires that the GOT-generating relocations of the PLT
are emitted into a contiguous subsection of the dynamic relocation
section described by dynamic tags DT_JMPREL, DT_PLTRELSZ, and
DT_PLTREL (see <a href="index.html">Dynamic relocation
section(s)</a>).</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="data-linkage-and-plt-got-generation-by-complying-linkers">
<h3>Data linkage and [PLT]GOT generation by complying linkers</h3>
<p>For a discussion of terminology and an overview of issues please
refer to <a href="index.html">Making sense of
ABI-supported addressing modes</a>, and especially to <a href="index.html">ABI supported indirect addressing</a>.</p>
<p>In general, an extra level of indirection via a writable
location is required to address imported data. The writable
location corresponding to an imported symbol X is called the GOT
entry for X. If X is a function imported via a PLT entry, the
corresponding writable location is called the PLTGOT entry for
X.</p>
<p>GOT generation is platform-specific, because there is no GOT
layout that can work across platform families. For example, SVr4
and Windows DLL linkage models disagree about the required
collation order of GOT entries.</p>
<p>Under this ABI, GOT entries are generated by a platform-specific
post linker that processes GOT-generating dynamic relocation
directives [<a href="https://developer.arm.com/docs/ihi0044/latest">AAELF</a>].</p>
<p>(Aside: Because GOT-generation is the only SVr4-specific
post-linking operation, we expect that most static linkers will
offer an option to generate an SVr4 executable file directly. End
aside).</p>
<p>If an ABI-complying executable file is to be post-linked:</p>
<ul>
<li>Each GOT-generating static relocation directive must be copied
to the dynamic relocation section.</li>
<li>PLT entries must be generated and their associated relocation
directives emitted into a contiguous subsection of the dynamic
relocation section (see <a href="index.html">Procedure
linkage and other intra-call veneers</a>). These relocation
directives will cause a platform-specific post linker to generate
the PLTGOT when this is required by the platform.</li>
</ul>
<p>post linker only generates [PLT]GOT entries from
[PLT]GOT-generating relocation directives.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="encoding-symbol-pre-emption-in-bpabi-executable-files">
<h3>Encoding symbol pre-emption in BPABI executable files</h3>
<p>Under the SVr4 ABI, the dynamic linker implements symbol
pre-emption using a form of dynamic binding. The dynamic symbol
tables it loads contain all the information it needs.</p>
<p>Under the base platform ABI (BPABI), symbol binding is strictly
static (<a href="index.html">Dynamic binding</a>), and
using the tool flow depicted in <a href="index.html">Figure 2,
Base platform ABI tool flow and its relationship to concrete
platforms</a>, symbol pre-emption happens off line. Consequently,
pre-emption must be recorded in a BPABI executable file in a format
that a post linker can process and convert to platform-specific
relocation data.</p>
<div>
<div>
<div>
<div id="overview-of-pre-emption-maps">
<h4>Overview of pre-emption maps</h4>
<p>If there is to be any pre-emption when a process is created,
what to do must be recorded in the platform executable file
generated by the post linker from the corresponding BPABI
executable file.</p>
<p>The details of how symbol pre-emption might be implemented on a
particular platform are beyond the scope of this standard. No
platform is required to implement pre-emption, but conforming
linkers must generate the base platform ABI-defined structures that
allow a platform to implement pre-emption.</p>
<p>This base platform ABI specifies a dynamic segment structure -
the pre-emption map - that conforming static linkers can use to
record static binding pre-emption in a BPABI executable file. Each
entry in such a map records that the definition of some symbol X,
say, made by some BPABI DLL used as an input to the link step was
pre-empted by a definition of X made by the output executable file
or by another input DLL.</p>
<p>The ELF processor supplement [<a href="https://developer.arm.com/docs/ihi0044/latest">AAELF</a>]
specifies the content and encoding of pre-emption maps.</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="obligations-on-static-linkers-generating-pre-emption-maps">
<h4>Obligations on static linkers generating pre-emption maps</h4>
<p>During a BPABI executable file-generating link step a static
linker must generate pre-emption map entries recording that one
definition of X pre-empts all others whenever it notices that a
symbol X is:</p>
<ul>
<li>Defined with vague linkage (defined in a GRP_COMDAT section) in
a relocatable file input to the link step and defined by at least
one BPABI DLL input to the link step.</li>
<li>Or, defined by more than one BPABI DLL input to the link
step.</li>
</ul>
<p>The pre-empting definition of a symbol X is the one closest to
the root of the needs graph rooted in the output executable file.
All other definitions of X visible in this link step are
pre-empted.</p>
<p>We define closest to the root of the needs graph as follows.</p>
<ul>
<li>The root node of the needs graph corresponds to the output
executable file. The other nodes correspond to the DLLs input to
the link step.</li>
<li>At each node, outgoing directed edges are defined by the
DT_NEEDED entries in the dynamic section of the corresponding
executable file that name a DLL in the graph (a DLL used directly
in the current link step). At each node the order of outgoing edges
is the same as the order of the corresponding DT_NEEDED entries in
their dynamic section.</li>
<li>The definition closest to the root is the one first encountered
in a breadth-first traversal of the needs graph in which each node
is visited at most once.</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="how-a-post-linker-might-use-a-pre-emption-map">
<h4>How a post linker might use a pre-emption map</h4>
<p>This section hints at the obligations a post linker and its
associated platform might have to accept in order to implement
symbol pre-emption. It places no obligations on platforms using
this ABI.</p>
<p>When a leaf BPABI DLL (one that depends on no other DLL) is
linked, references to entities with vague linkage must,
nonetheless, be relocated as if they were imported. At this stage
there is nowhere to import them from, so they had better be
imported from self. In turn, that requires them to be exported from
self.</p>
<p>At this stage, a post linker might create a platform-specific
relocation directive that causes a derived platform DLL to use its
own definitions.</p>
<p>When any other kind of BPABI executable file is created, there
can be pre-emption of a symbol with vague linkage. This is not
necessarily the final pre-emption that will occur when a process is
created. For example, suppose that:</p>
<ul>
<li>BPABI DLLs B, C, and application A define X with vague
linkage.</li>
<li>BPABI DLL B is created in a link step that refers (only) to DLL
C.</li>
<li>Application A is created in a link step that refers to DLL B
and DLL C is not available to this link step.</li>
</ul>
<p>The BPABI DLL B must record in a pre-emption map entry that B::X
pre-empts C::X.</p>
<p>The post linker must translate this pre-emption map entry to,
for example, a special kind of dynamic relocation that a loader of
the platform DLL B will apply to platform DLL C (or, more
plausibly, to its dynamic relocations).</p>
<p>Similarly, the BPABI description of application A must record in
a pre-emption map entry that A::X pre-empts B::X. The post linker
must translate this pre-emption map entry to, for example, special
dynamic relocations that:</p>
<ul>
<li>
<p>loader of the platform application A will apply to
platform DLL B (or, more plausible, to platform DLL B's
relocations, exactly as in the case of platform DLL C).</p>
</li>
<li>
<p>A loader of the platform application A will apply
to platform DLL B's special relocations.</p>
<p>(Thus changing platform DLL B's relocation of platform DLL C's
reference to X from B::X to A::X).</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="obligations-on-static-linkers-in-support-of-post-linking">
<h3>Obligations on static linkers in support of post linking</h3>
<p>Static linkers must accept certain obligations to support post
linking. These can be derived by considering the BPABI view of an
executable ELF file (depicted in red in <a href="index.html">Figure 5, SVr4 and base platform views of the same
executable file components</a>) and how a post linker would
translate it.</p>
<ul>
<li>The loadable program headers (PT_LOAD) in a BPABI executable
file must describe the bare program RO, RW, and ZI regions
excluding the file header, directories, and other SVr4-specific
dynamic linking structures.</li>
<li>Nonetheless, a static linker must include all generated linkage
veneers (PLT entries) in the RO region.</li>
<li>The base addresses of the program segments must be set to
platform-specific values by unspecified Q-o-I means (such as linker
command-line options beyond the scope of this ABI).</li>
<li>GOT-generating relocation directives may need to be passed to
the post linker as dynamic relocations.</li>
<li>The address of a dynamic linking structure not included in any
loadable segment must be set to its offset in the file. (There are
no such structures in an SVr4 executable file - all are included in
the loadable segments).</li>
</ul>
<div>
<div>
<div>
<div id="post-linking-translation-concerns">
<h4>Post linking translation concerns</h4>
<p>post linker must:</p>
<ul>
<li>Translate the file header and directory structure.</li>
<li>Copy (and perhaps relocate) the read-only and read-write
regions of the program.</li>
<li>Create platform-specific dynamic linking data derived from the
SVr4/BPABI symbolic dynamic linking data.</li>
</ul>
<p>This can be accommodated within an SVr4-like format if:</p>
<ul>
<li>The program header for the read-only segment describes only the
RO region and the PLT, and excludes the ELF header, directory, and
other read-only dynamic linkage structures.</li>
<li>The program header for the writable segment describes only the
RW region and excludes any writable dynamic linkage
structures.</li>
<li>If needed, the GOT is described by GOT-generating relocation
directives in the executable file's dynamic relocation
section.</li>
</ul>
<p>If the base addresses of the program regions have not been set
to appropriate platform-specific values the post linker must
relocate them by processing the dynamic relocations created by the
static linker.</p>
<p>In a scheme using Windows DLL-like linkage, the equivalent of
the GOT is the collection of import address tables. These have a
different shape and size but, crucially, contain the same
program-specific data as a GOT. A post linker can certainly create
them - or a structure like them - from GOT-creating dynamic
relocation directives.</p>
<p>In the DLL-like models of Palm OS and Symbian OS, if an import
structure is needed, a post-linker can create it:</p>
<ul>
<li>At the end of the RO program segment (if it can be shared
between processes).</li>
<li>At the end of the RW program segment (if it must be private to
a process).</li>
</ul>
<p>(Aside: These details are platform-specific and depend on
whether the DSO will be ROM-resident, ROM-resident and patchable,
or only loaded into RAM. End aside).</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="summary-of-platform-specific-considerations">
<h2>Summary of Platform-Specific Considerations</h2>
<p>Refer to the earlier <a href="index.html">Figure 5, SVr4 and
base platform views of the same executable file components</a> for
a depiction of executable file content and to <a href="index.html">Terminology</a> for overview and
terminology.</p>
<div>
<div>
<div>
<div id="differences-between-svr4-and-bpabi-executable-files">
<h3>Differences between SVr4 and BPABI executable files</h3>
<p>The table, below, lists the differences between the executable
file components required in a Linux (SVr4-style) executable file
and the components required in a base platform executable file.</p>
<p>Where the differences are significant, we tabulate the
difference between producing a Linux DSO directly, and producing a
BPABI executable file that will be post linked to create a
platform-specific executable file.</p>
<table id="id12">
<caption>Table 5, Significant differences between SVr4 and base
platform executable files</caption>
<colgroup>
<col width="18%"/>
<col width="45%"/>
<col width="37%"/></colgroup>
<thead valign="bottom">
<tr>
<th>Executable file component</th>
<th>SVr4/Linux (DSO) requirement</th>
<th>Base platform (DLL) requirement</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>
<p>ELF header</p>
<p>[<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>,
4]</p>
</td>
<td>
<p>Must be present and first in the file.</p>
<p>Must be mapped by the RO segment program
header.</p>
</td>
<td>
<p>Must be present and first in file.</p>
<p>Must not be mapped by the RO segment program
header.</p>
</td>
</tr>
<tr>
<td>
<p>Program header table</p>
<p>[<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>,
4]</p>
</td>
<td>
<p>Must be present in the part of the file mapped by
the RO segment program header.</p>
<p>Mapped by a PT_PHDR-type program header which must
precede any PT_LOAD-type one.</p>
</td>
<td>
<p>Must be present in the file.</p>
<p>Must not be included in the RO segment.</p>
<p>Mapping by a PT_PHDR-type program header is
optional.</p>
</td>
</tr>
<tr>
<td>
<p>Name of program interpreter</p>
<p>[<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>,
5]</p>
</td>
<td>
<p>Must be present in the part of the file mapped by
the RO segment program header.</p>
<p>Mapped by a PT_INTERP-type p-header which must
precede any PT_LOAD-type one.</p>
</td>
<td>If present, must not be mapped by the RO segment program
header.</td>
</tr>
<tr>
<td>
<p>ABI note section [<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>,
5]</p>
<p>[<a href="http://refspecs.linuxfoundation.org/LSB_2.0.1/LSB-Core/LSB-Core/noteabitag.html">ABInote</a>,
7]</p>
</td>
<td>
<p>No generic SVr4 requirement.</p>
<p>The Linux Base Standard requires 0 and the needed kernel version
as 4 32-bit integers in the data portion of the note (e.g. 0, 2, 6,
0).</p>
<p>Mapped by a PT_NOTE-type p-header.</p>
</td>
<td>If present, must not be mapped by the RO segment program
header.</td>
</tr>
<tr>
<td>RO program region</td>
<td>
<p>Must be present in the part of the file mapped by
the RO segment program header.</p>
<p>Mapped by a PT_LOAD-type p-header which maps all read-only,
sharable components.</p>
<p>[<a href="index.html">Figure 5, SVr4 and base
platform views of the same executable file components</a>, upper,
blue, view]</p>
</td>
<td>
<p>Mapped by a PT_LOAD-type p-header which maps this
component and the PLT only.</p>
<p>[<a href="index.html">Figure 5, SVr4 and base
platform views of the same executable file components</a>, lower,
red, view]</p>
</td>
</tr>
<tr>
<td>RW program region</td>
<td>
<p>Initialized data must be present in the part of
the file mapped by the RW segment p-header. ZI data (.bss) follows
directly in memory.</p>
<p>Mapped by a PT_LOAD-type p-header which maps all
writable components.</p>
</td>
<td>
<p>Mapped by a PT_LOAD-type p-header which maps this
component only.</p>
<p>[<a href="index.html">Figure 5, SVr4 and base
platform views of the same executable file components</a>, lower ,
red, view]</p>
</td>
</tr>
<tr>
<td>
<p>Dynamic section [<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>,
5]</p>
<p>[<a href="index.html">The dynamic
segment and its related sections</a>]</p>
</td>
<td>
<p>Must be present in the part of the file mapped by
a PT_LOAD program header (usually the RO segment).</p>
<p>Mapped by a PT_DYNAMIC-type p-heade.</p>
</td>
<td>
<p>Must be present.</p>
<p>Mapped by a PT_DYNAMIC-type program header.</p>
</td>
</tr>
<tr>
<td>
<p>Shared object name</p>
<p>[<a href="index.html">Shared object
(DLL) name</a>]</p>
</td>
<td>Ignored in executable files, optional in shared objects.</td>
<td>Must be present in a DLL, set by Q-o-I means. Defaults to
basename(file-name).</td>
</tr>
<tr>
<td>
<p>Dynamic symbol table</p>
<p>[<a href="index.html">Dynamic symbol
table</a>]</p>
</td>
<td>Must be present in the part of the file mapped by the RO
segment program header.</td>
<td>
<p>Must be present in the file.</p>
<p>Must not be mapped by the RO segment.</p>
</td>
</tr>
<tr>
<td>
<p>Version data</p>
<p>[<a href="index.html">Symbol
versioning</a>]</p>
</td>
<td>Must be present in the part of the file mapped by the RO
segment program header.</td>
<td>
<p>Must be present in the file.</p>
<p>Must not be mapped by the RO segment.</p>
</td>
</tr>
<tr>
<td>
<p>Hash table [<a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF</a>,
5],</p>
<p>[<a href="index.html">Hash
table</a>]</p>
</td>
<td>Must be present in the part of the file mapped by the RO
segment program header.</td>
<td>
<p>Must be present in the file.</p>
<p>Must not be mapped by the RO segment.</p>
</td>
</tr>
<tr>
<td>
<p>Dynamic relocation section</p>
<p>[<a href="index.html">Dynamic
relocation section(s)</a>]</p>
</td>
<td>Must be present in the part of the file mapped by the RO
segment program header.</td>
<td>
<p>Must be present in the file.</p>
<p>Must not be mapped by the RO segment.</p>
</td>
</tr>
<tr>
<td>
<p>PLT</p>
<p>[<a href="index.html">Code generation
for intra-call veneers (PLT entries)</a>]</p>
</td>
<td>Must be present in the part of the file mapped by the RO
segment program header.</td>
<td>Must be present in the part of the file mapped by the RO
segment program header.</td>
</tr>
<tr>
<td>
<p>GOT, PLTGOT</p>
<p>[<a href="index.html">Data linkage and
[PLT]GOT generation by complying linkers</a>]</p>
</td>
<td>Must be present in the part of the file mapped by the RW
segment program header.</td>
<td>
<p>Must not be present.</p>
<p>Implicit in [PLT]GOT-generating relocations.</p>
</td>
</tr>
<tr>
<td>PLTGOT / GOT relocations</td>
<td>Must be present in the dynamic relocation section.</td>
<td>
<p>Must not be present.</p>
<p>Implicit in [PLT]GOT-generating relocations.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="differences-between-linking-for-svr4-and-the-bpabi">
<h3>Differences between linking for SVr4 and the BPABI</h3>
<p><a href="index.html">Table 6, Differences between SVr4 and
base platform static linking options and behavior</a>, lists the
differences between the static linker controlling options,
behaviors, and interpretations required to generate an Arm Linux
executable file, and those required to generate a base platform
executable file that can be post linked into a platform-specific
executable file.</p>
<p>Platform specific values of options are listed as
platform-specific (that is, no specific value is given here). The
list includes options that might be set by default or by linker
script.</p>
<table id="id13">
<caption>Table 6, Differences between SVr4 and base platform static
linking options and behavior</caption>
<colgroup>
<col width="23%"/>
<col width="33%"/>
<col width="44%"/></colgroup>
<thead valign="bottom">
<tr>
<th>Aspect</th>
<th>SVr4/Arm Linux requirement</th>
<th>Base platform (not SVr4) requirement</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>Base address</td>
<td>One platform-specific, read-only segment base address.</td>
<td>Separate, platform-specific, RO and RW segment base
addresses</td>
</tr>
<tr>
<td>Segment alignment</td>
<td>Page aligned (usually 4, 8, or 64KB).</td>
<td>
<p>Platform-specific alignment  8 bytes.</p>
<p>Program regions are sometimes offset with respect
to segment origins.</p>
</td>
</tr>
<tr>
<td>Value of a dynamic symbol</td>
<td>Target virtual address of the symbol prior to any dynamic
rebasing of the executable file.</td>
<td>Target address of the symbol prior to any dynamic rebasing of
the loadable segments.</td>
</tr>
<tr>
<td>
<p>Other intra-file address values</p>
<p>[<a href="index.html">Interpretation
of addresses in SVr4 executable files</a>]</p>
</td>
<td>Target virtual address prior to any dynamic rebasing of the
file (as if the file were mapped at its linker-assumed base
address).</td>
<td>File offset within the executable file.</td>
</tr>
<tr>
<td>
<p>PLT generation</p>
<p>[<a href="index.html">Code generation
for intra-call veneers (PLT entries)</a>]</p>
</td>
<td>
<p>Generated by the static linker.</p>
<p>No useful code generation options.</p>
<p>(A PLTGOT must always be generated).</p>
</td>
<td>
<p>Generated by the static linker.</p>
<p>Option to generate direct or PLTGOT-using PLT
entries for each of 3 PCS variants.</p>
</td>
</tr>
<tr>
<td>
<p>GOT generation</p>
<p>[<a href="index.html">Data linkage and
[PLT]GOT generation by complying linkers</a>]</p>
</td>
<td>
<p>Generated by the static linker.</p>
<p>No useful code generation options.</p>
<p>(A GOT must always be generated).</p>
</td>
<td>
<p>Not generated by the static linker.</p>
<p>Implicit in [PLT]GOT-generating dynamic
relocations</p>
</td>
</tr>
<tr>
<td>WEAK undefined symbols</td>
<td>
<p>Treated as any other undefined symbol.</p>
<p>The corresponding dynamic symbol inherits STB_WEAK
binding.</p>
</td>
<td>WEAK undefined symbols must be eliminated during static
linking. The relocated value is the ABI-defined NULL value of the
relocation.</td>
</tr>
<tr>
<td>
<p>Relocation reduction</p>
<p>[<a href="https://developer.arm.com/docs/ihi0044/latest">AAELF</a>]</p>
</td>
<td>Static relocations must be reduced to dynamic relocations by
the static linker.</td>
<td>PLTGOT- and GOT-generating relocations must be preserved in the
dynamic relocation section.</td>
</tr>
<tr>
<td>
<p>References</p>
<p>RO → RO</p>
</td>
<td>References from RO → RO are fully resolved, PC-relative [DSO]
or absolute, during linking.</td>
<td>Each not PC-relative reference RO → RO must be relocated by a
dynamic relocation [<a href="index.html#bpabi32-note1"/>].</td>
</tr>
<tr>
<td>
<p>References</p>
<p>RO → RW/ZI</p>
</td>
<td>References from RO → RW/ZI are resolved, PC-relative [DSO] or
absolute, during linking. (Dynamically relocated GOT entries
remain).</td>
<td>Each not SB-relative reference RO → RW/ZI must be relocated by
a dynamic relocation [<a href="index.html#bpabi32-note2"/>].</td>
</tr>
<tr>
<td>
<p>References</p>
<p>RW → RO</p>
</td>
<td>Each reference RW → RO must be relocated w.r.t the base of the
RO segment.</td>
<td>Each reference RW → RO must be relocated w.r.t the base of the
RO segment [<a href="index.html#bpabi32-note1"/>].</td>
</tr>
<tr>
<td>
<p>References</p>
<p>RW → RW/ZI</p>
</td>
<td>Each reference RW → RW/ZI must be relocated w.r.t the base of
the RO segment (there is only one base address).</td>
<td>Each reference RW → RW/ZI must be relocated w.r.t the RW
segment base [<a href="index.html#bpabi32-note3"/>].</td>
</tr>
<tr>
<td>References to ZI</td>
<td>References to BSS are fully resolved, PC-relative DSO] or
absolute, by the static linker.</td>
<td>Each reference to ZI must by relocated by a ZI-relative dynamic
relocation [<a href="index.html#bpabi32-note4"/>].</td>
</tr>
</tbody>
</table>
<div>
<div>
<div>
<div>
<p>Note</p>
<ol id="bpabi32-note1">
<li>The RO segment need not, in general, be loaded at its nominal
base address.</li>
</ol>
<ol id="bpabi32-note2">
<li>The RW segment can be loaded independently, not necessarily at
its nominal base address.</li>
</ol>
<ol id="bpabi32-note3">
<li>The RO and RW segments of a DLL are independently loadable. An
SVr4 DSO has a single base address.</li>
</ol>
<ol id="bpabi32-note4">
<li>This is so that a post linker can place generated RW data
between the RW region and the ZI region.</li>
</ol>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="some-post-linking-sketches">
<h2>Some Post Linking Sketches</h2>
<div>
<div>
<div>
<div id="post-linking-for-linux">
<h3>Post linking for Linux</h3>
<p>Post linking for Linux should never be needed. In practice it is
no more difficult for a static linker to generate a Linux
executable file directly in place of a BPABI executable file.</p>
<p>If post linking were required, the grayed entries in <a href="index.html">Table 5, Significant differences between SVr4 and
base platform executable files</a> show what would have to be
generated.</p>
<ul>
<li>
<p>Name of program interpreter (read-only).</p>
<p>Typically this causes an insertion into the RO segment. The RO
region of a DSO is position independent, but the RW region will be
displaced and may need to be relocated as a result. The RO region
of an application may also need to be relocated.</p>
</li>
<li>
<p>ABI note section (read-only).</p>
<p>This is not strictly required, but inserting it generates the
same issues as above.</p>
</li>
<li>
<p>GOT and PLTGOT (read-write).</p>
<p>These are required, and inserting them displaces the ZI (bss)
region. References to ZI must be relocated.</p>
</li>
<li>
<p>GOT relocation section and PLTGOT relocation
section (read-only).</p>
<p>These are required, and inserting them displaces the RW region
which may then need to be relocated.</p>
</li>
</ul>
<p>In addition, there is some required remapping of content by the
two program headers of type PT_LOAD and some changes of
interpretation of address values, as noted in <a href="index.html">Table 6, Differences between SVr4 and base
platform static linking options and behavior</a>.</p>
<p>All of this remapping and rebasing is straightforward.
Constructing the GOT, PLTGOT, and their corresponding dynamic
relocations is trickier and we sketch that here.</p>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>for each PLTGOT-generating relocation Type[Place](Symbol) in increasing place order
    if (not exists GOT(Symbol)) {
        create GOT(Symbol) labeled by GOTSYM(Symbol)
        emit the dynamic relocation R_ARM_JUMP_SLOT[GOTSYM(Symbol)](Symbol)
    }
    perform the relocation Type[Place](GOTSYM(Symbol))
for each GOT-generating relocation Type[Place](Symbol)
    if (not exists GOT(Symbol)) {
        create GOT(Symbol) labeled by GOTSYM(Symbol)
        emit the dynamic relocation R_ARM_GLOB_DAT[GOTSYM(Symbol)](Symbol)
    }
    perform the relocation Type[Place](GOTSYM(Symbol))
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p>The symbol GOTSYM(Symbol) exists only transiently during post
linking. It does not appear in the executable file.</p>
<p>The PLTGOT-generating relocation directives are those from the
subsection of the dynamic relocation section described by these
dynamic array entries:</p>
<table>
<colgroup>
<col width="23%"/>
<col width="30%"/>
<col width="47%"/></colgroup>
<tbody valign="top">
<tr>
<td>DT_JMPREL address</td>
<td>DT_PLTRELSZ table-size</td>
<td>DT_PLTREL type (= DT_REL or DT_RELA)</td>
</tr>
</tbody>
</table>
<p>The GOT-generating relocation directives are those from the
dynamic relocation section described by the following dynamic array
entries, excluding the PLTGOT-generating entries described
above.</p>
<table>
<colgroup>
<col width="27%"/>
<col width="34%"/>
<col width="39%"/></colgroup>
<tbody valign="top">
<tr>
<td>DT_REL[A] address</td>
<td>DT_REL[A]SZ table-size</td>
<td>DT_REL[A]ENT element-size</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div id="post-linking-for-dll-like-linkage">
<h3>Post linking for DLL-like linkage</h3>
<p>In this section, we describe post linking for Windows DLL-style
linkage in general terms.</p>
<p>The details for Palm OS and Symbian OS are specific to those
platforms. Major structural differences from the Windows linkage
model - such as whether import is indirect through an import
address table or direct via dynamic relocations - are controlled
through options to the compiler and static linker that determine
whether or not the post linker will see GOT-generating dynamic
relocations.</p>
<p>The post linker has re-writing, re-basing, and relocating chores
similar to those described in <a href="index.html">Post
linking for Linux</a>.</p>
<p>The executable file needs a new file header and a new directory
structure, and this alone could force relocation. To implement
Windows DLL-style linkage, it must also append import and export
data tables to the RO segment (so they can be shared among all
processes threading the DLL).</p>
<p>It is straightforward to construct an export data table.</p>
<ul>
<li>
<p>The name of this DLL is in the dynamic section
(identified by DT_SONAME).</p>
</li>
<li>
<p>Each exported symbol is identified in the dynamic
symbol table. Defined symbols with binding STB_GLOBAL or STB_WEAK
should be exported according to their visibility, as follows:</p>
<ul>
<li>STV_DEFAULT 0
<p>Exported.</p>
</li>
<li>STV_INTERNAL 1
<p>Not exported; this symbol was fully bound at
static link time.</p>
</li>
<li>STV_HIDDEN 2
<p>Not exported; this symbol was fully bound at
static link time [<a href="index.html#bpabi32-note5"/>].</p>
</li>
<li>STV_PROTECTED 3
<p>Exported; this symbol is visible but cannot
be pre-empted [<a href="index.html#bpabi32-note6"/>].</p>
</li>
</ul>
<div>
<div>
<div>
<div>
<p>Note</p>
<ol id="bpabi32-note5">
<li>An STV_HIDDEN object can be exported indirectly if its address
is exported. In the case of a code object there must be a single
address for all users. Under some ABIs a call from outside the
shared object must be made through the code object's PLT entry and
so the address of the object must be the address of its PLT entry.
Under this ABI, STV_HIDDEN and STV_INTERNAL are equivalent.</li>
</ol>
<ol id="bpabi32-note6">
<li>platform ABI need not support "Exported but cannot be
pre-empted". Indeed, a platform ABI need not support symbol
pre-emption.</li>
</ol>
</div>
</div>
</div>
</div>
</li>
</ul>
<p>Values of symbols (target address) may need to be adjusted.</p>
<p>Import data tables are a little trickier to construct.</p>
<ul>
<li>First, generate the array of import data table headers. Each
one corresponds to a DLL imported from.
<ul>
<li>The names of DLLs imported from can be obtained from the
version needed structures (<a href="index.html">Creating versions needed for symbols
undefined in an executable file</a>) associated with each undefined
symbol in the dynamic symbol table.</li>
</ul>
</li>
<li>Second, generate an import lookup table, hint/name table, and
import address table corresponding to each import header. Import
address table entries are GOT entries, in the terminology of
previous sections.
<ul>
<li>Each import address table entry is generated by a
GOT-generating relocation that cites undefined STB_GLOBAL symbol.
Each of these symbols is associated with a version needed structure
that names the DLL being imported from.</li>
<li>The processing of dynamic relocations now reduces to something
like the following.</li>
</ul>
</li>
</ul>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<pre>for each DLL imported from
    for each GOT-generating relocation Type[Place](Symbol)
        if (Symbol is undefined and Version(Symbol).DLL is DLL) {
            if (not exists GOT(Symbol)) {
                create Import_Address_Table[DLL][Symbol] labeled by GOTSYM(Symbol)
                add Symbol's name to the corresponding hint/name table entry
            }
            perform the relocation Type[Place](GOTSYM(Symbol))
        }
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p>Finally, the remaining (not GOT-generating) dynamic relocations
must be encoded in a platform-specific way.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
